%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
#include "system.h"
#include "symtable1.c"
#include "code.c"

// #include "symtable.c"

extern char yytext[];
int DEBUGP=0;
int error_flag=0;
extern int column;
extern int linenumber;
extern FILE *yyin;
int currentScope=0,internalScope=0;
int declaration_flag=0,parameter_flag=0,function=0;
int counter=0;
struct Attribute *temp_inherited;
struct Attribute *temp_Parameters;
struct Attribute *temp_expression;
char *funcName;
char *templabel;
int size=0,oldsize=0;
int assign_flag=0;
FILE  * fcgFile , *icgFile ;

char *start[1000],*end[1000],*funcEndLabel,currentDepth=0;
char *printcode;
int empty_func=0;
int switch_flag=0;
char *icg,*fcg,*icg1,s1[10000];

%}

%union
{
	int intValue;
	long longIntValue;
	float floatValue;
	double doubleValue;
	char charValue;
	char *string;
	struct SymEntry *sym;
						    //char *tree;	
	struct Attribute *attr;
	//struct SynAttribute *synattr;
}

%nonassoc STRING INTEGER LONGINTEGER HEXADECIMAL DECIMALFLOAT 
%nonassoc DECIMALDOUBLE FLOATVAL DOUBLEVAL CHARACTER ESCAPECHAR  HEXLITERAL
%nonassoc IFX
%nonassoc ELSE

%token <string> STRING
%token <intValue> INTEGER
%token <longIntValue> LONGINTEGER
%token <intValue> HEXADECIMAL
%token <longIntValue> LONGHEXADECIMAL
%token <floatValue> DECIMALFLOAT
%token <doubleValue> DECIMALDOUBLE
%token <floatValue> FLOATVAL
%token <doubleValue> DOUBLEVAL
%token <charValue> CHARACTER
%token <charValue> ESCAPECHAR
%token <string> HEXLITERAL
%token <string> IDENTIFIER


%token SIZEOF PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token XOR_ASSIGN OR_ASSIGN TYPE_NAME

%token TYPEDEF EXTERN STATIC AUTO REGISTER
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
%token STRUCT UNION ENUM ELLIPSIS

%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN

%nonassoc DOUBLE FLOAT INT SHORT STRUCT UNSIGNED LONG SIGNED VOID ENUM CHAR UNION ';'

%right ADD_ASSIGN SUB_ASSIGN MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN AND_ASSIGN OR_ASSIGN RIGHT_ASSIGN LEFT_ASSIGN XOR_ASSIGN
%right '=' '|' '!' '^'
%left OR_OP AND_OP RIGHT_OP LEFT_OP INC_OP DEC_OP PTR_OP LE_OP GE_OP EQ_OP NE_OP
%left ':' '<' '>'
%left '+' '-'
%left '*' '/' '%'
%right '(' '[' '{'
%left ')' ']' '}'
// ')' see later*******

%type <sym> identifier
%type <charValue>unary_operator
%type <attr>constant
%type <attr>primary_expression
%type <attr>postfix_expression
%type <attr>argument_expression_list
%type <attr>unary_expression
%type <attr>cast_expression
%type <attr>multiplicative_expression
%type <attr>additive_expression
%type <attr>shift_expression
%type <attr>relational_expression
%type <attr>equality_expression
%type <attr>and_expression
%type <attr>exclusive_or_expression
%type <attr>inclusive_or_expression
%type <attr>logical_and_expression
%type <attr>logical_or_expression
%type <attr>conditional_expression
%type <attr>assignment_expression
%type <charValue>assignment_operator
%type <attr>expression
%type <attr>constant_expression
%type <attr>declaration
%type <attr>declaration_specifiers
%type <attr>init_declarator_list
%type <attr>init_declarator
%type <attr>storage_class_specifier
%type <attr>type_specifier
%type <attr>struct_or_union_specifier
%type <attr>struct_or_union
%type <attr>struct_declaration_list
%type <attr>struct_declaration
%type <attr>specifier_qualifier_list
%type <attr>struct_declarator_list
%type <attr>struct_declarator
%type <attr>enum_specifier
%type <attr>enumerator_list
%type <attr>enumerator
%type <attr>type_qualifier
%type <attr>declarator
%type <attr>direct_declarator
%type <attr>pointer
%type <attr>type_qualifier_list
%type <attr>parameter_type_list
%type <attr>parameter_list
%type <attr>parameter_declaration
%type <attr>identifier_list
%type <attr>type_name
%type <attr>abstract_declarator
%type <attr>direct_abstract_declarator
%type <attr>initializer
%type <attr>initializer_list
%type <attr>statement
%type <attr>labeled_statement
%type <attr>compound_statement
%type <attr>compound_statement_list
%type <attr>compound_declaration_list
%type <attr>declaration_list
%type <attr>statement_list
%type <attr>expression_statement
%type <attr>selection_statement
//%type <attr>if_then_else_branch
%type <attr>iteration_statement
%type <attr>jump_statement
%type <attr>external_declaration
%type <attr>function_definition
%type <attr>strt1

%start strt

%%

new_scope : {
		currentScope++;	
		struct SymTableNode *temp;
		temp=CreateNewSymTableNode();
		temp->scope=tail[function]->scope+1;	
		tail[function]->next=temp;
		tail[function]=temp;
		empty_func=0;
	    }
	  ;
finish_scope : {//printf("\n%d,%d\n",currentScope,function);PrintSymTable();
		  if(currentScope>0)
		  {
		      PopSym(function);
		      currentScope--;	      
		  }
		  else
		  {
		      //empty_func=1;
		      global[1]=CreateNewSymTableNode();
		      tail[1]=global[1];
		      //InsertSymTable("if",0,0,function);
		  }
	      }
	      ;
		     	
identifier
	: IDENTIFIER	{	
				if(DEBUGP){
					printf("\nidentifier->IDENTIFIER\n");
				}
				struct SymEntry *p;
				if(parameter_flag==0)
				{				      
				      p=lookup($1,function);
				      //printf("\nCurrent Scope %d FOUND VARIABLE -%s-\n",currentScope,$1);
				      if(p == NULL){
					      p = InsertSymTable($1,currentScope,IDENTIFIER,function);
					      p->linenum = linenumber;
					      p->type = 0 ;	
					      p->offset = size;
					      size = size + 4;
					      p->keywordval=0;
					      p->isPointer=0;
					      p->isArray=0;
					      p->ArrayLimit=0;
					      p->isFunction=0;
					      p->numParameters=0;
					      for(counter=0;counter<MaxPar;counter++)
						  p->ParameterList[counter]=NULL;
					      //p=lookup($1,function);
					      //p->typeName = malloc(sizeof(char)*MaxTypeLen + 1);
					      //printf("\n_____________INSERTED VARIBLE : %s PRESENT in line : %d\n",p->id,p->linenum);
				      }	
				      else if(p->scope==currentScope)
				      {
					  //printf("\nVARIBLE : %s ALREADY PRESENT in line : %d  and its type is : %d \n",p->id,p->linenum,p->type);
				      }
				      //p->linenum=linenumber;				      
				}
				else
				{
				      p=(struct SymEntry *)malloc(sizeof(struct SymEntry)); 
				      p->id=(char *)malloc(sizeof(char)*strlen($1)+1);
				      strcpy(p->id,$1);
				      p->linenum=0;
				      p->type=0;
				      p->scope=1000;				     
				      p->keywordval=0;	//UNION, INT , etc.
				    
				      p->isPointer=0;
				      p->isArray=0;
				      p->ArrayLimit=0;
				      p->isFunction=0;
				      p->offset=-1;
				      p->width=0;
				      p->numParameters=0;
				      for(counter=0;counter<MaxPar;counter++)
					  p->ParameterList[counter]=NULL;
				}
				$$=p;   // Now define the attributes needed for the identifier and manipulate accordingly.
				//printf("\nCurrent Scope : %d  Function Num : %d \n",currentScope,function);
				//PrintSymEntry($$);
				//printf("\n%s : Scope %d : type : %d :currentScope %d,function %d\n",$$->id,$$->scope,$$->type,currentScope,function);   
			}
	;

constant
	: INTEGER
		  {
		    if(DEBUGP){
				printf("\nconstant->INTEGER\n");
			}
		    //printf("\n\nInteger Value %d\n",$1);
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->IntConstValue = (long long ) ($1);
		    //$$->qualifier=1;
		    $$->specifier=4;		    
		    $$->type=400;
		   }
	| LONGINTEGER
		  {
		    if(DEBUGP){
				printf("\nconstant -> LONGINTEGER\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->IntConstValue = (long long ) ($1);
		    //$$->qualifier=1;
		    $$->specifier=5;
		    $$->type=500;
		   }
	| HEXADECIMAL
		  {
		    if(DEBUGP){
				printf("\nconstant -> HEXADECIMAL\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->IntConstValue = (long long ) ($1);
		    //$$->qualifier=1;
		    $$->specifier=4;
		    $$->type=400;
		   }
	| LONGHEXADECIMAL
		  {
		    if(DEBUGP){
				printf("\nconstant -> LONGHEXADECIMAL\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->IntConstValue = (long long ) ($1);
		    //$$->qualifier=1;
		    $$->specifier=5;
		    $$->type=500;
		   }
	| DECIMALFLOAT
		  {
		    if(DEBUGP){
				printf("\nconstant -> DECIMALFLOAT\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->FloatConstValue = (float) ($1);
		    //$$->qualifier=1;
		    $$->specifier=6;
		    $$->type=600;
		   }
	| DECIMALDOUBLE
		  {
		    if(DEBUGP){
				printf("\nconstant -> DECIMALDOUBLE\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->FloatConstValue = (double ) ($1);
		    //$$->qualifier=1;
		    $$->specifier=7;
		    $$->type=700;
		   }
	| FLOATVAL
		  {
		    if(DEBUGP){
				printf("\nconstant -> FLOATVAL\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->FloatConstValue = (float) ($1);
		    //$$->qualifier=1;
		    $$->specifier=6;
		    $$->type=600;
		   }
	| DOUBLEVAL
		  {
		    if(DEBUGP){
				printf("\nconstant -> DOUBLEVAL\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    $$->FloatConstValue = (double ) ($1);
		    //$$->qualifier=1;
		    $$->specifier=7;
		    $$->type=700;
		   }
	| CHARACTER
		  {
		    if(DEBUGP){
				printf("\nconstant -> CHARACTER\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    //$$->qualifier=1;
		    $$->specifier=2;
		    //$$->isPointer=1;
		    //$$->StringValue=(char *)malloc(sizeof(char)*2);		    
		    //$$->StringValue[0]=$1;
		    $$->IntConstValue=$1;
		    //$$->StringValue[1]='\0';
		    $$->type=200;
		   }
	| ESCAPECHAR
		  {
		    if(DEBUGP){
				printf("\nconstant -> ESCAPECHAR\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    //$$->qualifier=1;
		    $$->specifier=2;
		    //$$->isPointer=1;
		    //$$->StringValue=(char *)malloc(sizeof(char)*2);		    
		    //$$->StringValue[0]=$1;
		    //$$->StringValue[1]='\0';
		    $$->IntConstValue=$1;
		    $$->type=200;
		   }
	| HEXLITERAL
		  {
		    if(DEBUGP){
				printf("\nconstant -> HEXLITERAL\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    //$$->qualifier=1;
		    $$->specifier=2;
		    $$->isString=1;
		    $$->StringValue=(char *)malloc(sizeof(char)*strlen($1));		    
		    strcpy($$->StringValue,$1);
		    $$->type=200;
		   }
	| STRING
		  {
		    if(DEBUGP){
				printf("\nconstant -> STRING\n");
			}
		    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
		    $$=initAttr($$);
		    //$$->qualifier=1;
		    $$->specifier=2;
		    $$->isString=1;
		    $$->StringValue=(char *)malloc(sizeof(char)*strlen($1));		    
		    strcpy($$->StringValue,$1);
		    $$->type=200;		    
		   }
	;

primary_expression
	: identifier  {		
			    if(DEBUGP){
				printf("\nprimary_expression -> identifier\n");
			    }
			    if($1->type == 0)
			    {
				 error_flag=1;
				 printf ( "\nError : %s not defined\n" , $1->id );
			    }
			    //$$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    //$$->type=$1->type;
			    $$=PassSymEntry($1);
			    $$->specifier=$$->type/100;
		      }
	| constant
		  {
		    if(DEBUGP){
				printf("\nprimary_expression -> constant\n");
			    }
			    //$$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    //$$->type=$1->type;
			    $$=PassAttribute($1);
			    $$->qualifier=1;
			    
			    //------------code generation-------------//
			    
			    
			    if($$->type==400)
			      {
				    
				    $$->id=(char *)malloc(10);
				    strcpy($$->id,getNewTemp());
				    $$->offset = size;
				    size = size + 4;
				    
				    
				    sprintf( s1 , "\t%s = %d\n" , $$->id , (int)$1->IntConstValue);
				    icg=replicate(s1);
				    sprintf( s1 , "\tli $t0 %d\n" , (int)$1->IntConstValue);
				    fcg=replicate(s1);
				    sprintf( s1 , "\tsw $t0 %s\n" , toAddr ($$->offset));
				    fcg=append(fcg,s1);
				    $$->code=replicate(fcg);
				    $$->icode=replicate(icg);	
    //PrintAttribute($$);
				}
				/*if($$->type==600 ) //Float ke liye
			      {
				    
				    $$->id=(char *)malloc(10);
				    strcpy($$->id,getNewTemp());
				    $$->offset = size;
				    size = size + 4;
				    
				    
				    sprintf( icg , "\t%s = %d\n" , $$->id , (int)$1->IntConstValue);
				    
				    sprintf( fcg , "\tli $t0 %d\n" , (int)$1->IntConstValue);
				    sprintf( fcg , "\tsw $t0 %s\n" , toAddr ($$->offset));
				    
				}*/
			    		    
		   }
	| '(' expression ')'
		  {
		    if(DEBUGP){
				printf("\nprimary_expression -> (expression)\n");
			    }
			    $$=PassAttribute($2);
		   }

	;

postfix_expression
	: primary_expression
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> primary_expression\n");
			}
			 $$=PassAttribute($1);
		   }
	| postfix_expression '[' expression ']'
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> postfix_expression[expression]\n");
			}
			$$=PassAttribute($1);
//PrintAttribute($1);
			if($1->isArray!=1)
			{
			      printf("\nError :Trying to access an index of a non array.\n");
			      error_flag=1;
			}
			else    
			{
			    $$->isArray=0;
			   //char *fcg , * icg , s1[10000];
			    $$->id = getNewTemp();
			    if(assign_flag==1)
			    {
				$$->offset = size;
				size += 4;
				icg=replicate($3->icode);
				fcg=replicate($3->code);
				sprintf( s1 , "\t%s = %s[%s]\n" , $$->id , $1->id , $3->id );
				icg = append(icg,s1);
	      
				sprintf( s1 , "\tli $t0 %d\n",$1->offset);
				fcg=append(fcg,s1);
				sprintf( s1 , "\tlw $t1 %s\n",toAddr($3->offset));
				fcg=append(fcg,s1);				

				sprintf( s1 , "\tsll $t1 $t1 2\n");
				fcg=append(fcg,s1);
				
				sprintf( s1 , "\tadd $t0 $t0 $t1\n");
				fcg=append(fcg,s1);
				sprintf( s1 , "\tsub $t1 $sp $t0\n");
				fcg=append(fcg,s1);
				sprintf( s1 , "\tlw $t1 0($t1)\n");
				fcg=append(fcg,s1);
				sprintf( s1 , "\tsw $t1 %s\n",toAddr($$->offset));
				fcg=append(fcg,s1);
				$$->icode=replicate(icg);
				$$->code=replicate(fcg);
			 }
			  else
			  {
			      $$->qualifier=3;
			      $$->offset = size;
				size += 4;
			    				
				sprintf( s1 , "\t%s = %s[%s]\n" , $$->id , $1->id , $3->id );
				icg = replicate(s1);
	      
				fcg=replicate($3->code);
				sprintf( s1 , "\tli $t0 %d\n",$1->offset);
				fcg=append(fcg,s1);
				sprintf( s1 , "\tlw $t1 %s\n",toAddr($3->offset));
				fcg=append(fcg,s1);
				
				sprintf( s1 , "\tsll $t1 $t1 2\n");
				fcg=append(fcg,s1);
				
				sprintf( s1 , "\tadd $t0 $t0 $t1\n");
				fcg=append(fcg,s1);
				sprintf( s1 , "\tsub $t1 $sp $t0\n");
				fcg=append(fcg,s1);
				sprintf( s1 , "\tsw $t1 %s\n",toAddr($$->offset));
				fcg=append(fcg,s1);
				$$->icode=replicate(icg);
				$$->code=replicate(fcg);
			    }
			}
			//$$->ArrayLimit=(int)$3->IntConstValue+1; //Assuming the accessed is the highest index.
		   }
	| postfix_expression '(' ')'
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> postfix_expression()\n");
			}
			$$=PassAttribute($1);
			
			if($1->isFunction!=1)
			{
			      printf("\nError :Trying to access an index of a non array.\n");
			      error_flag=1;
			}
			$$->isFunction=0;	//We do not consider a function call as a function.	
			if(error_flag==0)
			{
			    
			    $$->id=getNewTemp();
			    $$->offset=size;
			    size+=4;
			    fcg=replicate("");
			    icg=replicate("");			 			    

			    sprintf(s1,"\taddi $sp $sp %d\n",MaxFunctionLength);
			    fcg=append(fcg,s1);
			    sprintf(s1,"\tjal %s\n",$1->id);
			    fcg=append(fcg,s1);
			    if($1->type!=100)
			    {
				  sprintf(s1,"\t%s = call function %s\n",$$->id,$1->id);
				  icg=append(icg,s1);
				  sprintf(s1,"\tlw $t0 %s\n",toAddr(0));
			    }
			    else
			    {
				  sprintf(s1,"\tcall function %s\n",$1->id);
				  icg=append(icg,s1);
				  sprintf(s1,"\tli $t0 $0\n");
			    }
			    fcg=append(fcg,s1);
			    sprintf(s1,"\taddi $sp $sp -%d\n",MaxFunctionLength);
			    fcg=append(fcg,s1);
			    sprintf(s1,"\tsw $t0 %s\n",toAddr($$->offset));
			    fcg=append(fcg,s1);
			    $$->code=replicate(fcg);
			      $$->icode=replicate(icg);
			}
		   }
	| postfix_expression '(' argument_expression_list ')'
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> postfix_expression(argument_expression_list)\n");
			}//PrintAttribute($3);
			$$=PassAttribute($1);
			$$->isFunction=0; //We do not consider a function call as a function.
			$$->numParameters=0;

			if($1->isFunction!=1)
			{
			      //$$->isFunction=0;
			      printf("\nError :Trying to access a non-function as a function.\n");
			      error_flag=1;
			      			      
			      /*for(counter=0;counter<$3->numParameters;counter++)
			      {
				    $$->ParameterList[counter]=PassAttribute($3->ParameterList[counter]);
			      }*/
			}
			else
			{
			    
			    /*if($1->numParameters!=$3->numParameters)
			    {
				  error_flag=1;
				  printf("\nError : Parameters do not match\n");
			    }
			    else*/
			    {
				for(counter=0;counter<$1->numParameters;counter++)
				{
				      if($1->ParameterList[counter]->type!=$3->ParameterList[counter]->type)
				      {
					    error_flag=1;
					    printf("\nError : Parameter %d 's Type does not match\n",counter);
				      }
				}
			    }
			}
			if(error_flag==0)
			{	//PrintAttribute($3);
			    if(strcmp($1->id,"print_t")==0)
			    {
				 
				  $$->id=getNewTemp();
				  icg=replicate($3->icode);
				  fcg=replicate($3->code);
				  sprintf(s1,"\n\tprint_t %s\n\n",$3->ParameterList[0]->id);
				  icg=append(icg,s1);

				  sprintf(s1,"\n\tlw $t0 %s\n",toAddr($3->ParameterList[0]->offset));
				  fcg=append(fcg,s1);
				  sprintf(s1,"\tli $v0 1\n");
				  fcg=append(fcg,s1);
				  sprintf(s1,"\tmove $a0 $t0\n");
				  fcg=append(fcg,s1);
				  sprintf(s1,"\tsyscall\n");
				  fcg=append(fcg,s1);
				  sprintf(s1,"\tli $v0 4\n");
				  fcg=append(fcg,s1);
				  sprintf(s1,"\tla $a0 str\n");
				  fcg=append(fcg,s1);
				  sprintf(s1,"\tsyscall\n\n");
				  fcg=append(fcg,s1);

				  $$->icode=replicate(icg);
				  $$->code=replicate(fcg);
			    }
			    else
			    {

				
				$$->id=getNewTemp();
				$$->offset=size;
				size+=4;
				fcg=replicate($3->code);
				icg=replicate($3->icode);
    //printf("\n%s\n%s\n",fcg,icg);
				for(counter=0;counter<$3->numParameters;counter++)
				{
				    sprintf(s1,"\tlw $t0 %s\n",toAddr($3->ParameterList[counter]->offset));
				    fcg=append(fcg,s1);
				    sprintf(s1,"\tsw $t0 %d($sp)\n",(MaxFunctionLength-(counter+1)*4));
				    fcg=append(fcg,s1);

				    sprintf(s1,"\tparam %s\n",$3->ParameterList[counter]->id);
				    icg=append(icg,s1);
				    
				}
				

				sprintf(s1,"\taddi $sp $sp %d\n",MaxFunctionLength);
				fcg=append(fcg,s1);
				sprintf(s1,"\tjal %s\n",$1->id);
				fcg=append(fcg,s1);
				if($1->type!=100)
				{
				      sprintf(s1,"\t%s = call function %s\n",$$->id,$1->id);
				      icg=append(icg,s1);
				      sprintf(s1,"\tlw $t0 %s\n",toAddr(0));
				}
				else
				{
				      sprintf(s1,"\tcall function %s\n",$1->id);
				      icg=append(icg,s1);
				      sprintf(s1,"\tli $t0 $0\n");
				}
				fcg=append(fcg,s1);
				sprintf(s1,"\taddi $sp $sp -%d\n",MaxFunctionLength);
				fcg=append(fcg,s1);
				sprintf(s1,"\tsw $t0 %s\n",toAddr($$->offset));
				fcg=append(fcg,s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);//PrintAttribute($);
			    }
			}
			    
		   }
	| postfix_expression '.' identifier	//shayad enum and struct type ke liye hai. baad mein dekhna hai.
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> postfix_expression.identifier\n");
			}
		   }
	| postfix_expression PTR_OP identifier	//struct ya pointer type ke liye hai. baad mein dekhna hai.
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> postfix_expression PTR_OP identifier\n");
			}
		   }
	| postfix_expression INC_OP
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> postfix_expression INC_OP\n");
			}
			$$=PassAttribute($1);
			if($1->specifier == 1||$1->specifier ==10 ||$1->specifier ==11 ||$1->specifier ==12 ||$1->specifier ==13||$1->specifier ==14 || $1-> isString==1||$1->specifier==1)
			{
			    error_flag=1;
			    printf("\nError : Cannot perform ++ on this kind of data type.\n");
			}
			
			
			$$->offset = size;
			size = size + 4 ;
			$$->id = (char*) malloc(10);
			strcpy($$->id,getNewTemp());
			//printf("\n------------------%d\n",assign_flag);
			  sprintf( s1 , "%s\t%s++\n",$1->icode,$1->id );
			  icg=replicate(s1);

			  sprintf( s1 , "%s\tlw $t0 %s\n" ,$1->code, toAddr($1->offset) );
			  fcg=replicate(s1);
			  if(assign_flag==1)
			  {
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\taddi $t0 $t0 1\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($1->offset) );
			  }
			  else
			  {
				  sprintf( s1 , "\taddi $t0 $t0 1\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($1->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
			  }
			  fcg = append(fcg , s1);

			  $$->code=replicate(fcg);
			  $$->icode=replicate(icg);
		   }
	| postfix_expression DEC_OP
		  {
		    if(DEBUGP){
				printf("\npostfix_expression -> postfix_expression DEC_OP\n");
			}
			$$=PassAttribute($1);
			if($1->specifier == 1||$1->specifier ==10 ||$1->specifier ==11 ||$1->specifier ==12 ||$1->specifier ==13||$1->specifier ==14 || $1-> isString==1||$1->specifier==1)
			{
			    error_flag=1;
			    printf("\nError : Cannot perform -- on this kind of data type.\n");
			}
			  
				  
			  $$->offset = size;
			  size = size + 4 ;
			  $$->id = (char*) malloc(10);
			  strcpy($$->id,getNewTemp());
			  
			  sprintf( s1 , "%s\t%s--\n",$1->icode,$1->id );
			  icg=replicate(s1);

			  sprintf( s1 , "%s\tlw $t0 %s\n" ,$1->code, toAddr($1->offset) );
			  fcg=replicate(s1);

			if(assign_flag==1)
			  {
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\taddi $t0 $t0 -1\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($1->offset) );
				  fcg = append(fcg , s1);
			  }
			  else
			  {				  
				  sprintf( s1 , "\taddi $t0 $t0 -1\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($1->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
			  }

			  $$->code=replicate(fcg);
			  $$->icode=replicate(icg);
		   }
	;

argument_expression_list
	: assignment_expression
	      {
		    if(DEBUGP){
				printf("\nargument_expression_list -> assignment_expression\n");
			}
			$$=(struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->ParameterList[0]=PassAttribute($1);
			$$->numParameters=1;
			$$->code=replicate($1->code);
			$$->icode=replicate($1->icode);
			//PrintAttribute($$);
		   }
	| argument_expression_list ',' assignment_expression
		{
		    if(DEBUGP){
				printf("\nargument_expression_list -> argument_expression_list , assignment_expression\n");
			}
			$$=PassAttribute($1);
			$$->ParameterList[$$->numParameters]=PassAttribute($3);
			$$->numParameters++;
			if($3->code!=NULL)
			{
			$$->code=append($$->code,$3->code);
			$$->icode=append($$->icode,$3->icode);
			}
			//PrintAttribute($$);
		   }
	;

unary_expression
	: postfix_expression
	      {
		    if(DEBUGP){
				printf("\nunary_expression -> postfix_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| INC_OP unary_expression	//Aisi situation mein shayad sirf machine code generation mein pange aayenge offset wagarah mein.
	      {
		    if(DEBUGP){
				printf("\nunary_expression -> INC_OP unary_expression\n");
			}
			$$=PassAttribute($2);
			
			if($2->specifier == 1||$2->specifier ==10 ||$2->specifier ==11 ||$2->specifier ==12 ||$2->specifier ==13||$2->specifier ==14 || $2-> isString==1||$2->qualifier==1)
			{
			    error_flag=1;
			    printf("\nCannot perform preincrement ++ on this kind of data type.\n");
			}

		    
				  
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s\t++%s\n",$2->icode,$2->id );
				  icg=replicate(s1);

				  sprintf( s1 , "%s\tlw $t0 %s\n" ,$2->code, toAddr($2->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\taddi $t0 $t0 1\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($2->offset) );
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			

		   }
	| DEC_OP unary_expression
		{
		    if(DEBUGP){
				printf("\nunary_expression -> DEC_OP unary_expression\n");
			}
			$$=PassAttribute($2);
			
			if($2->specifier == 1||$2->specifier ==10 ||$2->specifier ==11 ||$2->specifier ==12 ||$2->specifier ==13||$2->specifier ==14 || $2-> isString==1||$2->qualifier==1)
			{
			    error_flag=1;
			    printf("\nCannot perform pre -- on this kind of data type.\n");
			}

	  

				
				  
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s\t++%s\n",$2->icode,$2->id );
				  icg=replicate(s1);

				  sprintf( s1 , "%s\tlw $t0 %s\n" ,$2->code, toAddr($2->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\taddi $t0 $t0 -1\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($2->offset) );
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);




		   }    
	| unary_operator cast_expression
		{
		    if(DEBUGP){
				printf("\nunary_expression -> unary_operator cast_expression\n");
			}
			
			$$=PassAttribute($2);			
			
	      
			if($1 == '!')
			{
			       //------------code generation-------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s\t%s = !%s\n",$2->icode,$$->id , $2->id );
				  icg=replicate(s1);

				  sprintf( s1 , "%s\tlw $t0 %s\n" ,$2->code, toAddr($2->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tli $t1 0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t2 $t0 $t1\n" );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t3 $t1 $t0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tadd $t1 $t2 $t3\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tli $t0 1\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsub $t0 $t0 $t1\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
      
		      if($1 == '~')
		      {
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s\t%s = !%s\n",$2->icode,$$->id , $2->id );
				  icg=replicate(s1);

				  sprintf( s1 , "%s\tlw $t0 %s\n" ,$2->code, toAddr($2->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tnor $t1 $t0 $0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t1 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			  }
			
		      if($1 == '-')
		      {
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s\t%s = !%s\n",$2->icode,$$->id , $2->id );
				  icg=replicate(s1);

				  sprintf( s1 , "%s\tlw $t0 %s\n" ,$2->code, toAddr($2->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tsub $t1 $0 $t0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t1 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			  }
			if($1 == '&')
			{
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s\t%s = &%s\n",$2->icode,$$->id , $2->id );
				  icg=replicate(s1);
			
				  fcg=replicate($2->code);
				  sprintf( s1 , "%s\n\n\tli $t0 %d\n" ,$2->code, ($2->offset) );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsub $t1 $sp $t0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t1 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			  }
			  if($1 == '*')
			{
				  $$->isPointer=0;
				//char *fcg , * icg , s1[10000];
				  $$->id = getNewTemp();
			      if($2->isPointer!=1)
			      {
				     error_flag=1;
				     printf("\nError : Invalid Operation on a non-pointer\n");
			      }
			      else
			      {
				  if(assign_flag==1)
				  {
				      $$->offset = size;
				      size += 4;
				      sprintf( s1 , "\t%s = *%s\n" , $$->id , $2->id );
				      icg = append(icg,s1);
		    
				      sprintf( s1 , "\tlw $t0 %s\n",toAddr($2->offset));
				      fcg=append(fcg,s1);
				    
				      sprintf( s1 , "\tlw $t1 0($t0)\n",toAddr($2->offset));
				      fcg=append(fcg,s1);				

				      sprintf( s1 , "\tsw $t1 %s\n",toAddr($$->offset));
				      fcg=append(fcg,s1);
				      $$->icode=replicate(icg);
				      $$->code=replicate(fcg);
				}
				else
				{
				      $$->qualifier=3;
				      $$->offset = size;
				      size += 4;
							      
				      sprintf( s1 , "\t%s = Address of *%s\n" , $$->id , $2->id );
				      icg = replicate(s1);
		    
				      fcg=replicate($2->code);
				      
				      sprintf( s1 , "\tlw $t0 %s\n",toAddr($2->offset));
				      fcg=append(fcg,s1);
				      
				      sprintf( s1 , "\tsw $t0 %s\n",toAddr($$->offset));
				      fcg=append(fcg,s1);
				      $$->icode=replicate(icg);
				      $$->code=replicate(fcg);
				  }
			      }
			  }


		   }
	| SIZEOF unary_expression
		{
		    if(DEBUGP){
				printf("\nunary_expression -> SIZEOF unary_expression\n");
			}
			$$=(struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->IntConstValue = (long long ) ($2->width); //Yahan kuch hona chahiye lekin kya??
			$$->qualifier=1;
			$$->specifier=5;
			$$->type=500;
		   }
	| SIZEOF '(' type_name ')'
	      {
		    if(DEBUGP){
				printf("\nunary_expression -> SIZEOF ( type_name )\n");
			}
			$$=(struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->IntConstValue = (long long ) ($3->width); //Yahan kuch hona chahiye lekin kya??
			$$->qualifier=1;
			$$->specifier=5;
			$$->type=500;
		   }
	;

unary_operator
	: '&'
		  {
		    if(DEBUGP){
				printf("\nunary_operator -> &\n");
			}
		     $$='&'; 
		   }
	| '*'
		  {
		    if(DEBUGP){
				printf("\nunary_operator -> *\n");
			}
		    $$='*';
		   }
	| '+'
		  {
		    if(DEBUGP){
				printf("\nunary_operator -> +\n");
			}
		    $$='+';
		   }
	| '-'
		  {
		    if(DEBUGP){
				printf("\nunary_operator -> -\n");
			}
		    $$='-';
		   }
	| '~'
		   {
		    if(DEBUGP){
				printf("\nunary_operator -> ~\n");
			}
		    $$='~';
		   }
	| '!'
		  {
		    if(DEBUGP){
				printf("\nunary_operator -> !\n");
			}
		    $$='!';
		   }
	;

cast_expression
	: unary_expression
	      {
		    if(DEBUGP){
				printf("\ncast_expression -> unary_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| '(' type_name ')' cast_expression
	      {
		    //type casting done int/long/char/float/double
		    if(DEBUGP){
				printf("\ncast_expression -> ( type_name ) cast_expression\n");
			}
			$$=PassAttribute($2);
			if($4->id!=NULL)
			{
			    $$->id=(char *)malloc(sizeof(char)*strlen($4->id)+1);
			    strcpy($$->id,$4->id);//*******Wapas yahan se karna hai
			}
			if($4->isArray==1 || $4->isString==1)
			{
			    error_flag=1;
			    printf("\nError : Cannot Type Cast an Array or a String\n");
			}
			else
			{
			    //printf("\n$2-specifier %d $4-specifier %d\n",$2-specifiew);
			    $$->scope=$4->scope;
			    if(($2->specifier==4 || $2->specifier==5) && ($4->specifier==4 || $4->specifier==5)) 
			    {
				$$->IntConstValue=$4->IntConstValue;
			    }
			    else if(($2->specifier==4 || $2->specifier==5) && ($4->specifier==6 || $4->specifier==7)) 
			    {
				$$->IntConstValue=(long long)$4->FloatConstValue;
			    }
			    else if(($2->specifier==6 || $2->specifier==7) && ($4->specifier==4 || $4->specifier==5)) 
			    {
				$$->FloatConstValue=(double)$4->IntConstValue;
			    }
			    else if(($2->specifier==6 || $2->specifier==7) && ($4->specifier==6 || $4->specifier==7)) 
			    {
				$$->FloatConstValue=$4->FloatConstValue;
			    }
			    else if(($2->specifier==4 || $2->specifier==5) && ($4->specifier==2)) 
			    {
				$$->IntConstValue=(int)$4->StringValue[0];
			    }
			    else
			    {
				error_flag=1;
				printf("\nError : Unsupported Casting for this Compiler\n");
			    }
			    /*
			    $$->IntConst=$4->IntConst;			    
			    if($4->StringValue!=NULL)
			    {
				$$->StringValue=(char *)malloc(sizeof(char)*strlen($4->StringValue)+1);
				strcpy($$->StringValue,$4->StringValue);
			    }*/
			 }
		   }
	;

multiplicative_expression
	: cast_expression
	      {
		    if(DEBUGP){
				printf("\nmultiplicative_expression -> cast_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| multiplicative_expression '*' cast_expression
	      {
		    if(DEBUGP){
				printf("\nmultiplicative_expression -> multiplicative_expression '*' cast_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Cannot multiply incompatible data types.\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;


				    
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				  //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s * %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg=replicate(s1);

				  sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tmult $t0 $t1\n" );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tmflo $t2\n" );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tsw $t2 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1); 
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
				  
			}
	      }
	| multiplicative_expression '/' cast_expression
	      {
		    if(DEBUGP){
				printf("\nmultiplicative_expression -> multiplicative_expression / cast_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Cannot divide incompatible data types.\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;

				   
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				  //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s / %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg=replicate(s1);

				  sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tdiv $t0 $t1\n" );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tmflo $t2\n" );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tsw $t2 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1); 
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
	      }
	| multiplicative_expression '%' cast_expression
	      {
		    if(DEBUGP){
				printf("\nmultiplicative_expression -> multiplicative_expression MOD cast_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3) || !(($3->specifier==4||$3->specifier==5)&&($1->specifier==4||$1->specifier==5));
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Cannot Take Mod incompatible data types.\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;

				  
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				  //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s mod %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg=replicate(s1);

				  sprintf( s1 , "%s%s\tlw $t0 %s\n", $1->code,$3->code, toAddr($1->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tdiv $t0 $t1\n" );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tmfhi $t2\n" );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tsw $t2 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1); 
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
		   }
	;

additive_expression
	: multiplicative_expression
	      {
		    if(DEBUGP){
				printf("\nadditive_expression -> multiplicative_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| additive_expression '+' multiplicative_expression
	      {
		    if(DEBUGP){
				printf("\nadditive_expression -> additive_expression '+' multiplicative_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Cannot Add incompatible data types.\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				  //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s + %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg=replicate(s1);

				  sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tadd $t2,$t0,$t1\n" );
				  fcg=append(fcg,s1); 
				  sprintf( s1 , "\tsw $t2 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1); 
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
			//PrintAttribute($$);
			//PrintAttribute($1);PrintAttribute($3);printf("\nerrorflag %d\n",error_flag);
		   }
	| additive_expression '-' multiplicative_expression
	      {
		    if(DEBUGP){
				printf("\nadditive_expression -> additive_expression '-' multiplicative_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Cannot Subtract incompatible data types.\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				    //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s - %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg=replicate(s1);
				  sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsub $t2 $t0 $t1\n" );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t2 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
		   }
	;

shift_expression
	: additive_expression
		  {
		    if(DEBUGP){
				printf("\nshift_expression -> additive_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| shift_expression LEFT_OP additive_expression
		  {
		    if(DEBUGP){
				printf("\nshift_expression -> shift_expression LEFT_OP additive_expression\n");
			}
			if(!($1->specifier==4 || $1->specifier==5 || ($1->specifier==2 && $1->isString==0))||!($3->specifier==4 || $3->specifier==5||($3->specifier==2 && $3->isString==0))||$1->isString==1||$3->isString==1||$1->isPointer==1||$3->isPointer==1||$1->isFunction==1||$3->isFunction==1)
			{
			      error_flag=1;
			      printf("\nError : Incompatible Types for Left Shift.\n");
			}
			$$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=$1->specifier;
			$$->qualifier=2;
			$$->storage=$1->storage;
			$$->type=$$->storage*10 + $$->specifier*100;
			//--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s << %d\n",$1->icode,$3->icode,$$->id , $1->id , (int)$3->IntConstValue);
				  icg=replicate(s1);
				  sprintf( s1 , "%s%s\tlw $t0 %s\n" , $1->code,$3->code,toAddr($1->offset) );
				  fcg=replicate(s1);
				  sprintf( s1 , "\tsll $t1 $t0 %d\n", (int)$3->IntConstValue );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t1 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		   }
	| shift_expression RIGHT_OP additive_expression
		  {
		    if(DEBUGP){
				printf("\nshift_expression -> shift_expression RIGHT_OP additive_expression\n");
			}
			if(!($1->specifier==4 || $1->specifier==5 || ($1->specifier==2 && $1->isString==0))||!($3->specifier==4 || $3->specifier==5||($3->specifier==2 && $3->isString==0))||$1->isString==1||$3->isString==1||$1->isPointer==1||$3->isPointer==1||$1->isFunction==1||$3->isFunction==1)
			{
			      error_flag=1;
			      printf("\nError : Incompatible Types for Right Shift.\n");
			}
			$$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=$1->specifier;
			$$->qualifier=2;
			$$->storage=$1->storage;
			$$->type= $$->storage*10 + $$->specifier*100;
			//--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  
				  sprintf( s1 , "%s%s\t%s = %s >> %d\n",$1->icode,$3->icode,$$->id , $1->id , (int)$3->IntConstValue);
				  icg = replicate(s1);
				  sprintf( s1 , "%s%s\tlw $t0 %s\n" , $1->code,$3->code,toAddr($1->offset) );
				  fcg = replicate(s1);
				  sprintf( s1 , "\tsrl $t1 $t0 %d\n", (int)$3->IntConstValue );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t1 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg ,s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		   }
	;

relational_expression
	: shift_expression
		  {
		    if(DEBUGP){
				printf("\nrelational_expression -> shift_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| relational_expression '<' shift_expression
		  {
		    if(DEBUGP){
				printf("\nrelational_expression -> relational_expression '<' shift_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Incompatible data types for Comparision(<).\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				  //printf("\n-----------\n");PrintAttribute($1);PrintAttribute($3);printf("\n-----------\n");  
				  //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  
				    icg=replicate("");
				    fcg=replicate("");
				    if($1->qualifier==3)
				    {
					  sprintf(s1,"array value at %s",$1->id);
					  icg=append(icg,s1);

					  sprintf(s1,"\tlw $t9 %s\n",toAddr($1->offset));  
					  fcg=append(fcg,s1);
					  
				    }
				    else
				    {
					  sprintf(s1,"%s",$1->id);
					  icg=append(icg,s1);

					  sprintf(s1,"\tli $t0 %d\n",$1->offset);  
					  fcg=append(fcg,s1);
					  sprintf(s1,"\tsub $t9 $sp $t0\n");  
					  fcg=append(fcg,s1);
				    }	   
				    if($3->qualifier==3)
				    {
					  sprintf(s1,"array value at %s",$3->id);
					  icg1=replicate(s1);

					  sprintf(s1,"\tlw $t8 %s\n",toAddr($3->offset));  
					  fcg=append(fcg,s1);
					  
				    }
				    else
				    {
					  sprintf(s1,"%s",$3->id);
					  icg1=replicate(s1);

					  sprintf(s1,"\tli $t0 %d\n",$3->offset);  
					  fcg=append(fcg,s1);
					  sprintf(s1,"\tsub $t8 $sp $t0\n");  
					  fcg=append(fcg,s1);
				    }
				  sprintf( s1 , "%s%s\t%s = %s < %s\n",$1->icode,$3->icode,$$->id , icg , icg1);
				  icg = append(icg,s1);

				  sprintf( s1 , "%s%s\tlw $t0 0($t9)\n" ,$1->code,$3->code );
				  fcg = append(fcg,s1);
				  sprintf( s1 , "\tlw $t1 0($t8)\n");
				  fcg = append (fcg , s1);
				  sprintf( s1 , "\tslt $t2 $t0 $t1\n" );
				  fcg = append (fcg ,s1);
				  sprintf( s1 , "\tsw $t2 %s\n" , toAddr($$->offset) );
				  fcg = append (fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);//PrintAttribute($$);
		
			}

		   }
	| relational_expression '>' shift_expression
		  {
		    if(DEBUGP){
				printf("\nrelational_expression -> relational_expression '>' shift_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Incompatible data types for Comparision(>).\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				    //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  
				    icg=replicate("");
				    fcg=replicate("");
				    sprintf( s1 , "%s%s",$1->icode,$3->icode);
				   icg = append (icg,s1);
				    
				  sprintf( s1 , "%s",$1->code );
				  fcg = append (fcg,s1);
				  sprintf( s1 , "%s",$3->code );
				  fcg = append (fcg,s1);

				    if($1->qualifier==3)
				    {
					  sprintf(s1,"array value at %s",$1->id);
					  icg=append(icg,s1);

					  sprintf(s1,"\tlw $t9 %s\n",toAddr($1->offset));  
					  fcg=append(fcg,s1);
					  
				    }
				    else
				    {
					  sprintf(s1,"%s",$1->id);
					  icg=append(icg,s1);

					  sprintf(s1,"\tli $t0 %d\n",$1->offset);  
					  fcg=append(fcg,s1);
					  sprintf(s1,"\tsub $t9 $sp $t0\n");  
					  fcg=append(fcg,s1);
				    }	   
				    if($3->qualifier==3)
				    {
					  sprintf(s1,"array value at %s",$3->id);
					  icg1=replicate(s1);

					  sprintf(s1,"\tlw $t8 %s\n",toAddr($3->offset));  
					  fcg=append(fcg,s1);
					  
				    }
				    else
				    {
					  sprintf(s1,"%s",$3->id);
					  icg1=replicate(s1);

					  sprintf(s1,"\tli $t0 %d\n",$3->offset);  
					  fcg=append(fcg,s1);
					  sprintf(s1,"\tsub $t8 $sp $t0\n");  
					  fcg=append(fcg,s1);
				    }
				  
				  sprintf( s1 , "\t%s = %s > %s\n",$$->id, icg , icg1);
				   icg = append (icg,s1);
				  
				  sprintf( s1 , "\tlw $t0 0($t9)\n" );
				  fcg = append (fcg,s1);
				  sprintf( s1 , "\tlw $t1 0($t8)\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t2 $t1 $t0\n" );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t2 %s\n" , toAddr($$->offset) );	
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		  //PrintAttribute($$);
			}//PrintAttribute($1);PrintAttribute($3);
		   }
	| relational_expression LE_OP shift_expression
		  {
		    if(DEBUGP){
				printf("\nrelational_expression -> relational_expression LE_OP shift_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Incompatible data types for Comparision(<=).\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				// --------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  
				  sprintf( s1 , "%s%s\t%s = %s <= %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);
			      
				  sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				  fcg = replicate (s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsub $t2 $t1 $t0\n" );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t3 $t2 $0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tli $t4 1\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsub $t4 $t4 $t3\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t4 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
		   }
	| relational_expression GE_OP shift_expression
		  {
		    if(DEBUGP){
				printf("\nrelational_expression -> relational_expression GE_OP shift_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Incompatible data types for Comparision(>=).\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				    
				  //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
  
				  
				  sprintf( s1 , "%s%s\t%s = %s >= %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);


				  sprintf( s1 , "%s%s\tlw $t0 %s\n" , $1->code,$3->code,toAddr($1->offset) );
				  fcg = replicate (s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsub $t2 $t0 $t1\n" );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t3 $t2 $0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tli $t4 1\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsub $t4 $t4 $t3\n");	
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t4 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);

				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		 
			}
		   }
	;

equality_expression
	: relational_expression
		  {
		    if(DEBUGP){
				printf("\nequality_expression -> relational_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| equality_expression EQ_OP relational_expression
		  {
		    if(DEBUGP){
				printf("\nequality_expression -> equality_expression EQ_OP relational_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Incompatible data types for Equal Check(==).\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;

				    //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  
				  sprintf( s1 , "%s%s\t%s = %s == %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);
  
				  sprintf( s1 , "%s%s\tlw $t0 %s\n" , $1->code,$3->code,toAddr($1->offset) );
				  fcg = replicate (s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t2 $t0 $t1\n" );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t3 $t1 $t0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tadd $t1 $t2 $t3\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tli $t0 1\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsub $t0 $t0 $t1\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
				  
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
		   }
	| equality_expression NE_OP relational_expression
		  {
		    if(DEBUGP){
				printf("\nequality_expression -> equality_expression NE_OP relational_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1) // Incompatible in operations.
			{
				printf("\nError : Incompatible data types for Equal Check(!=).\n");
				$$=PassAttribute($1); //As a part of error recovery.
			}
			else
			{
				  $$=MergeAttributes3Code($1,$3);
				  $$->qualifier=2;
				
				  //--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  
				  sprintf( s1 , "%s%s\t%s = %s == %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);
				
				  sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				  fcg = replicate (s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t2 $t0 $t1\n" );
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tslt $t3 $t1 $t0\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tadd $t1 $t2 $t3\n");
				  fcg = append(fcg , s1);
				  sprintf( s1 , "\tsw $t1 %s\n" , toAddr($$->offset) );
				  fcg = append(fcg , s1);
  
				   $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			}
		   }
	;

and_expression
	: equality_expression
		  {
		    if(DEBUGP){
				printf("\nand_expression -> equality_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| and_expression '&' equality_expression
		  {
		    if(DEBUGP){
				printf("\nand_expression -> and_expression '&' equality_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1){
				printf("\nError: Incomaptible for & operator\n");
			}
			$$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=$1->specifier;
			$$->qualifier=2;
			$$->storage=$1->storage;
			$$->type=$$->storage*10 + $$->specifier*100;

			//--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				   
				  sprintf( s1 , "%s%s\t%s = %s & %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);
  
				  sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				  fcg = replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tand $t3 $t0 $t1\n" );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t3 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1);
    
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		
		   }
	;
exclusive_or_expression
	: and_expression
		  {
		    if(DEBUGP){
				printf("\nexclusive_or_expression -> and_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| exclusive_or_expression '^' and_expression
		  {
		    if(DEBUGP){
				printf("\nexclusive_or_expression -> exclusive_or_expression '^' and_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1){
				printf("\nError: Incomaptible for Xor ^ operator\n");
			}
			$$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=$1->specifier;
			$$->qualifier=2;
			$$->storage=$1->storage;
			$$->type= $$->storage*10 + $$->specifier*100;
			//--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s & %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);

				  sprintf( s1 , "%s%s\tlw $t0 %s\n" , $1->code,$3->code,toAddr($1->offset) );
				  fcg = replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\txor $t3 $t0 $t1\n" );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t3 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1);

				   $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		   }
	;

inclusive_or_expression
	: exclusive_or_expression
		  {
		    if(DEBUGP){
				printf("\ninclusive_or_expression -> exclusive_or_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| inclusive_or_expression '|' exclusive_or_expression
		  {
		    if(DEBUGP){
				printf("\ninclusive_or_expression -> inclusive_or_expression '|' exclusive_or_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1){
				printf("\nError: Incomaptible for | operator\n");
			}
			$$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=$1->specifier;
			$$->qualifier=2;
			$$->storage=$1->storage;
			$$->type= $$->storage*10 + $$->specifier*100;
  
			//--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				    
				  sprintf( s1 , "%s%s\t%s = %s & %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);

				  sprintf( s1 , "%s%s\tlw $t0 %s\n" , $1->code,$3->code,toAddr($1->offset) );
				  fcg = replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tor $t3 $t0 $t1\n" );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t3 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1);
		 
				   $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		   }
	;

logical_and_expression
	: inclusive_or_expression
		  {
		    if(DEBUGP){
				printf("\nlogical_and_expression -> inclusive_or_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| logical_and_expression AND_OP inclusive_or_expression
		  {
		    if(DEBUGP){
				printf("\nlogical_and_expression -> logical_and_expression AND_OP inclusive_or_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1){
				printf("\nError: Incomaptible for Logical And && operator\n");
				$$=PassAttribute($1);
			}
			else
			{    $$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			    $$=initAttr($$);
			    $$->specifier=$1->specifier;
			    $$->qualifier=2;
			    $$->storage=$1->storage;
			    $$->type= $$->storage*10 + $$->specifier*100;
		
			    //-------------------------code generation ---------------------
				      $$->offset = size;
				      size = size + 4 ;
				      $$->id = (char*) malloc(10);
				      strcpy($$->id,getNewTemp());
				      
				      sprintf( s1 , "%s%s\t%s = %s == %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				      icg = replicate (s1);

				      sprintf( s1 , "%s%s\tlw $t0 %s\n" ,$1->code,$3->code, toAddr($1->offset) );
				      fcg = replicate(s1);
				      sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				      fcg=append(fcg,s1);
				      sprintf( s1 , "\tslt $t2 $t0 $0\n" );
				      fcg=append(fcg,s1);
				      sprintf( s1 , "\tslt $t3 $0 $t0\n");
				      fcg=append(fcg,s1);
				      sprintf( s1 , "\tadd $t4 $t2 $t3\n");
				      fcg=append(fcg,s1);
				      sprintf( s1 , "\tslt $t2 $t1 $0\n" );
				      fcg=append(fcg,s1);
				      sprintf( s1 , "\tslt $t3 $0 $t1\n");
				      fcg=append(fcg,s1);
				      sprintf( s1 , "\tadd $t5 $t2 $t3\n");
				      fcg=append(fcg,s1);
				      sprintf( s1 , "\tand $t0 $t5 $t4\n");
				      fcg=append(fcg,s1);  
				      sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				      fcg=append(fcg,s1);

				      $$->code=replicate(fcg);
				      $$->icode=replicate(icg);
			  }
		   }
	;
logical_or_expression
	: logical_and_expression
		  {
		    if(DEBUGP){
				printf("\nlogical_or_expression -> logical_and_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| logical_or_expression OR_OP logical_and_expression
		  {
		    if(DEBUGP){
				printf("\nlogical_or_expression -> logical_or_expression OR_OP logical_and_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$3);
			if(error_flag==1){
				printf("\nError: Incomaptible for Logical And && operator\n");
			}
			$$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=$1->specifier;
			$$->qualifier=2;
			$$->storage=$1->storage;
			$$->type= $$->storage*10 + $$->specifier*100;
  
			//--------------------------code generation ---------------------
				  $$->offset = size;
				  size = size + 4 ;
				  $$->id = (char*) malloc(10);
				  strcpy($$->id,getNewTemp());
				  
				  sprintf( s1 , "%s%s\t%s = %s == %s\n",$1->icode,$3->icode,$$->id , $1->id , $3->id);
				  icg = replicate (s1);

				  sprintf( s1 , "%s%s\tlw $t0 %s\n" , $1->code,$3->code,toAddr($1->offset) );
				  fcg = replicate(s1);
				  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($3->offset) );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tslt $t2 $t0 $0\n" );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tslt $t3 $0 $t0\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tadd $t4 $t2 $t3\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tslt $t2 $t1 $0\n" );
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tslt $t3 $0 $t1\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tadd $t5 $t2 $t3\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tor $t0 $t5 $t4\n");
				  fcg=append(fcg,s1);
				  sprintf( s1 , "\tsw $t0 %s\n" , toAddr($$->offset) );
				  fcg=append(fcg,s1);
				  
				   $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
		   }
	;

conditional_expression
	: logical_or_expression
		  {
		    if(DEBUGP){
				printf("\nconditional_expression -> logical_or_expression\n");
			}
			$$=PassAttribute($1);
		   }
	| logical_or_expression '?' expression ':' conditional_expression	//Baad mein karte hain
		  {
		    if(DEBUGP){
				printf("\nconditional_expression -> logical_or_expression '?' expression ':' conditional_expression\n");
			}
			error_flag=CheckBeforeMerge($1,$1)||CheckBeforeMerge($3,$5);
			if(error_flag==1){
				printf("\nError: Incomaptible for Logical And && operator\n");
			}
			$$=PassAttribute($3);	//For now daal diya hai dekhna padega...probably values(IntConstValue etc) change karni padegi...
			$$->qualifier=2;
		   }
	;

assignment_expression
	: conditional_expression
		  {
		    if(DEBUGP){
				printf("\nassignment_expression -> conditional_expression\n");
			}
			$$=PassAttribute($1);  //PrintAttribute($$);
		   }
	| unary_expression assignment_operator assignment_expression 	
		  {
		    if(DEBUGP){
				printf("\nassignment_expression -> unary_expression assignment_operator assignment_expression \n");
			}			
			$$=PassAttribute($1);				      
			if($1->qualifier>0 &&$1->qualifier!=3)	//qualifier is 1 for a constant number and 2 for 3 code. In either case left side nahi ho sakta.
			{
			      error_flag=1;
			      printf("\nError : Invalid Assignment. Left side should have Lvalue\n");
			}
			else if($1->isFunction==1)
			{
			      error_flag=1;
			      printf("\nError : Function is defined like a variable.\n");
			}
			else if($1->isArray==0)
			{
			     
			     if($3->numParameters>0)
			      {
				    error_flag=1;
				    printf("\nError : Assigning a List to Variable.\n");//PrintAttribute($3);
			      }

			     else if($1->isPointer==1)
			      {
				    if(!((($3->type==200 && $3->isString!=1)||$3->type==400||($3->type==500&&$3->isPointer==0))\
				    ||($3->type==$1->type && $3->isPointer==1)||($1->specifier==2 && $3->isString==1)))
				    {
					   error_flag=1;
					   printf("\nError : Invalid Assignment to Pointer.\n");
				     }		
				    else
				    {
					  $$->icode=replicate($3->icode);
					  $$->code=replicate($3->code);
					  sprintf(s1,"\tpointer value at %s = %s\n",$1->id,$3->id);
					  $$->icode=append($$->icode,s1);

					  sprintf(s1,"\tlw $t0 %s\n",toAddr($3->offset));
					  $$->code=append($$->code,s1);

					  sprintf(s1,"\tsw $t0 %s\n",toAddr($1->offset));
					  $$->code=append($$->code,s1);
				    }
			      }
			      else
			      {
				    //$1 is not an array, pointer, function so can be int,long,double,float,char
				    if($3->isFunction==1||$3->isArray==1||$3->isPointer==1||$3->isString==1)
				    {
					error_flag=1;
					printf("\nError : Invalid Assignment Method to the variable.\n");
				    }
				  
				    //------------code generation-------------//
				     
//PrintAttribute($1);			f
				    fcg=replicate($1->code);icg=replicate($1->icode);
				    if($1->qualifier==3)
				    {
					  sprintf(s1,"array value at %s",$1->id);
					  icg=append(icg,s1);

					  sprintf(s1,"\tlw $t9 %s\n",toAddr($1->offset));  
					  fcg=append(fcg,s1);
					  
				    }
				    else
				    {
					  sprintf(s1,"%s",$1->id);
					  icg=append(icg,s1);

					  sprintf(s1,"\tli $t0 %d\n",$1->offset);  
					  fcg=append(fcg,s1);
					  sprintf(s1,"\tsub $t9 $sp $t0\n");  
					  fcg=append(fcg,s1);
				    }
				    if($2 == '=' )
				    {
					  sprintf( s1 , "%s\t%s = %s\n" ,$3->icode, icg , $3->id );						
					  icg=append(icg,s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t0 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '+' )
				    {
					  sprintf( s1 , "%s\t%s += %s\n" ,$3->icode, icg , $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tadd $t1 $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '-' )
				    {
					  sprintf( s1 , "%s\t%s -= %s\n" ,$3->icode, icg, $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsub $t1 $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '<' )
				    {
					  
					  sprintf( s1 , "%s\t%s <<= %d\n" ,$3->icode, icg , (int)$3->IntConstValue );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsll $t1 $t1 %d\n", (int)$3->IntConstValue );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '>' )
				    {
					  
					  sprintf( s1 , "%s\t%s >>= %d\n" ,$3->icode, icg , (int)$3->IntConstValue );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsrl $t1 $t1 %d\n", (int)$3->IntConstValue );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '&' )
				    {
					  sprintf( s1 , "%s\t%s &= %s\n" ,$3->icode, icg , $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tand $t1 $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '|' )
				    {
					  sprintf( s1 , "%s\t%s |= %s\n" ,$3->icode, icg , $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tor $t1 $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '^' )
				    {
					  sprintf( s1 , "%s\t%s ^= %s\n" ,$3->icode, icg , $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\txor $t1 $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '*' )
				    {
					  sprintf( s1 , "%s\t%s *= %s\n" ,$3->icode, icg , $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tmult $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tmflo $t1\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '/' )
				    {
					  sprintf( s1 , "%s\t%s /= %s\n" ,$3->icode, icg , $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tdiv $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tmflo $t1\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    if($2 == '%' )
				    {
					  sprintf( s1 , "%s\t%s mod= %s\n" ,$3->icode, icg , $3->id );						
					  icg=replicate(s1);

					  sprintf( s1 , "%s",$3->code);
					  fcg=replicate(s1);
					  sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tlw $t1 %s\n" , toAddr($1->offset) );
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tdiv $t1 $t0\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tmfhi $t1\n");
					  fcg=append(fcg,s1);
					  sprintf( s1 , "\tsw $t1 0($t9)\n");
					  fcg=append(fcg,s1);
					  $$->code=replicate(fcg);
					  $$->icode=replicate(icg);
					  //PrintAttribute($$);
				    }
				    //PrintAttribute($$);

			      }
			 }
			 else	//Can be an array only
			  {
			      error_flag=1;
			      printf("\nError : Cannot perform assignment to array like a variable.\n");				
			  }
			  assign_flag=0;
			  //PrintAttribute($$);
		   }	
	;

equal_to
	:
	'='
	  {
		  assign_flag=1;
	  }
	;
assignment_operator
	: equal_to
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='=';
		   }	  
	| MUL_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='*';
			assign_flag=1;
		   }	  
	| DIV_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='/';
			assign_flag=1;
		   }	  
	| MOD_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='%';
			assign_flag=1;
		   }	  
	| ADD_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='+';
			assign_flag=1;
		   }	  
	| SUB_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='-';
			assign_flag=1;
		   }	  
	| LEFT_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='<';
			assign_flag=1;
		   }	  
	| RIGHT_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='>';
			assign_flag=1;
		   }	  
	| AND_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='&';
			assign_flag=1;
		   }	  
	| XOR_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='^';
			assign_flag=1;
		   }	  
	| OR_ASSIGN
	      {
		    if(DEBUGP){
				printf("\nassignment_operator found\n");
			}
			$$='|';
			assign_flag=1;
		   }	  
	;

expression
	: assignment_expression
	      {
		    if(DEBUGP){
				printf("\nexpression -> assignment_expression\n");
			}
			$$=PassAttribute($1);
			if(switch_flag==0)
			{
			    temp_expression=PassAttribute($$);
			}
			//PrintAttribute($$);
		   }	  
	| expression ',' assignment_expression
	      {
		    if(DEBUGP){
				printf("\nexpression -> expression ',' assignment_expression\n");
			}		
			$$=PassAttribute($1);
			$$->code=append($$->code,$3->code);
			$$->icode=append($$->icode,$3->icode);
			$$->id=NULL;
		   }	  
	;

constant_expression
	: conditional_expression
	      {
		    if(DEBUGP){
				printf("\nconstant_expression -> conditional_expression\n");
			}		
			$$=PassAttribute($1);
		   }	  
	;

declaration
	: declaration_specifiers ';' 
	      {
		    if(DEBUGP){
				printf("\ndeclaration -> declaration_specifiers ';' \n");
			}
			declaration_flag=0;
			$$=(struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=1;
			$$->type=100;      
			$$->code=(char *)malloc(sizeof(char)*2);
			$$->icode=(char *)malloc(sizeof(char)*2);
			strcpy($$->code,"");
			strcpy($$->icode,"");
			assign_flag=0;
			
			//printf("\n Value of temp_inherited-----");
			//PrintAttribute(temp_inherited);
			temp_inherited=initAttr( temp_inherited) ;		
			temp_Parameters=initAttr( temp_Parameters) ;		
			
			//printf("\n new Value of temp_inherited -----");
			//PrintAttribute(temp_inherited);				
		    }
	| declaration_specifiers error { 
			if(DEBUGP){
				printf("\ndeclaration -> declaration_specifiers error \n");
			      }
			    declaration_flag=0;
			    $$=(struct Attribute*)malloc(sizeof (struct Attribute));

			    $$=initAttr($$);	
			    $$->code=(char *)malloc(sizeof(char)*2);
			    $$->icode=(char *)malloc(sizeof(char)*2);
			    strcpy($$->code,"");
			    strcpy($$->icode,"");
			    //printf("\n Value of temp_inherited-----");
			    //PrintAttribute(temp_inherited);
			    temp_inherited=initAttr( temp_inherited) ;		
			    temp_Parameters=initAttr( temp_Parameters) ;		
			    //printf("\n Value of temp_inherited-----");
			    //PrintAttribute(temp_inherited);				
			    $$->specifier=1;
			    $$->type=100;
			    error_flag=1;
			    printf("\nError : semicolon missing\n ") ; 
		    }
	| declaration_specifiers init_declarator_list ';'	
		    {
			if(DEBUGP){
				printf("\ndeclaration -> declaration_specifiers init_declarator_list ';'\n");
			}
			declaration_flag=0;
			$$=(struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=1;
			$$->type=100;
			//printf("\n Value of temp_inherited-----");
			//PrintAttribute(temp_inherited);
			temp_inherited=initAttr( temp_inherited) ;
			temp_Parameters=initAttr( temp_Parameters) ;		
			$$->code=(char *)malloc(sizeof(char)*strlen($2->code)+1);
			$$->icode=(char *)malloc(sizeof(char)*strlen($2->icode)+1);
			strcpy($$->code,$2->code);
			strcpy($$->icode,$2->icode);
			assign_flag=0;
			//PrintAttribute($$);
			//printf("\n Value of temp_inherited-----");
			//PrintAttribute(temp_inherited);				
		    }
	| declaration_specifiers init_declarator_list error 
		    { 
			if(DEBUGP){
				printf("\ndeclaration -> declaration_specifiers init_declarator_list error\n");
			}
			declaration_flag=0;
			$$=(struct Attribute*)malloc(sizeof (struct Attribute));
			$$=initAttr($$);
			$$->specifier=1;
			$$->type=100;
			assign_flag=0;
			//printf("\n Value of temp_inherited-----");
			//PrintAttribute(temp_inherited);
			temp_inherited=initAttr( temp_inherited) ;
			temp_Parameters=initAttr( temp_Parameters) ;		
			$$->code=(char *)malloc(sizeof(char)*strlen($2->code)+1);
			$$->icode=(char *)malloc(sizeof(char)*strlen($2->icode)+1);
			strcpy($$->code,$2->code);
			strcpy($$->icode,$2->icode);	
			//printf("\n Value of temp_inherited-----");
			//PrintAttribute(temp_inherited);
			error_flag=1;
			printf("\nError : semicolon missing \n") ; 
		    }
	;

declaration_specifiers
	: type_qualifier	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_qualifier\n");
			}
		    if(parameter_flag==0)
			  declaration_flag=1;
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		    $$=PassAttribute($1);
		   }
	| type_specifier 
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_specifier\n");
			}
		    if(parameter_flag==0)
			  declaration_flag=1;
//PrintAttribute($1);
		    $$=PassAttribute($1);

		   }
	| storage_class_specifier	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> storage_class_specifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute($1);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_qualifier type_specifier	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_qualifier type_specifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_specifier type_qualifier		//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_specifier type_qualifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_specifier storage_class_specifier		//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_specifier storage_class_specifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| storage_class_specifier type_specifier		//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> storage_class_specifier type_specifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| storage_class_specifier type_qualifier		//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> storage_class_specifier type_qualifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_qualifier storage_class_specifier	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_qualifier storage_class_specifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_qualifier type_specifier storage_class_specifier	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_qualifier type_specifier storage_class_specifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_qualifier storage_class_specifier type_specifier	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_qualifier storage_class_specifier type_specifier\n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| storage_class_specifier type_specifier type_qualifier		//Not Supported 
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> storage_class_specifier type_specifier type_qualifier \n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| storage_class_specifier type_qualifier type_specifier 	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> storage_class_specifier type_qualifier type_specifier \n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_specifier type_qualifier storage_class_specifier 	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_specifier type_qualifier storage_class_specifier \n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	| type_specifier storage_class_specifier type_qualifier 	//Not Supported
	      {
		    if(DEBUGP){
				printf("\ndeclaration_specifiers -> type_specifier storage_class_specifier type_qualifier \n");
			}
		    declaration_flag=1;
		    $$=PassAttribute(temp_inherited);
		    error_flag=1;
		    printf("\nError : This C finctionality is not supported\n");
		   }
	;

init_declarator_list
	: init_declarator
	      {
		    if(DEBUGP){
				printf("\ninit_declarator_list -> init_declarator \n");
			}
			$$=PassAttribute($1);			
		   }							      
	| init_declarator_list ',' init_declarator
	      {
		    if(DEBUGP){
				printf("\ninit_declarator_list ->  init_declarator_list ',' init_declarator\n");
			}
			$$=PassAttribute($1);
			$$->code=append($$->code,$3->code);
			$$->icode=append($$->icode,$3->icode);
		   }						
	;

init_declarator
	: declarator equal_to initializer	//Thodi type checking karni padegi
	      {
		    if(DEBUGP){
				printf("\ninit_declarator ->declarator equal_to initializer\n");
			}
			/*printf("\n============================\n");
			  PrintAttribute($1);printf("\n===================================\n");PrintAttribute($3);*/
			$$=PassAttribute($1);				      
			if($1->isFunction==1)
			{
			      error_flag=1;
			      printf("\nError : Function is defined like a variable.\n");
			}
			else if($1->isArray==0)
			{
			     
			     if($3->numParameters>0)
			      {
				    error_flag=1;
				    printf("\nError : Assigning a List to Variable.\n");
			      }

			     else if($1->isPointer==1)
			      {
				    if(!((($3->type==200 && $3->isString!=1)||$3->type==400||($3->type==500&&$3->isPointer==0))\
				    ||($3->type==$1->type && $3->isPointer==1)||($1->specifier==2 && $3->isString==1)))
				    {
					   error_flag=1;
					   printf("\nError : Invalid Assignment to Pointer.\n");
				     }
				     struct SymEntry *p;
				     p=lookup($1->id,function);
				     p->offset=size;
				      size+=4;

				      

				     $$->icode=replicate($3->icode);
				      $$->code=replicate($3->code);
				      sprintf(s1,"\t%s %s\n",$1->id,($3->id));
				      $$->icode=append($$->icode,s1);
				      sprintf(s1,"\tlw $t0 %s\n",toAddr($3->offset));
				      $$->code=append($$->code,s1);
				      sprintf(s1,"\tsw $t0 %s\n",toAddr(p->offset));
				      $$->code=append($$->code,s1);
			      }
			      else
			      {
				    //$1 is not an array, pointer, function so can be int,long,double,float,char
				    if($3->isFunction==1||$3->isArray==1||$3->isPointer==1||$3->isString==1)
				    {
					error_flag=1;
					printf("\nError : Invalid Assignment to the variable.\n");
				    }
				    
				   //------------------------code generation ------------------------
				    if($1->type == 400 && $3->type== 400)
				     {
					
					sprintf(s1 , "%s\t%s = %s\n",$3->icode, $1->id , $3->id);
					icg=replicate(s1);
					sprintf(s1,"%s",$3->code);
					fcg=replicate(s1);
					sprintf(s1 , "\tlw $t0 %s\n", toAddr($3->offset));
					fcg=append(fcg,s1);
					sprintf(s1 , "\tsw $t0 %s\n", toAddr($1->offset)); 
					fcg=append(fcg,s1);
					$$->code=replicate(fcg);
					$$->icode=replicate(icg);
  //PrintAttribute($$);
				      }
			      }
			 }
			 else	//Can be an array only
			  {	$$->isArray=1;
				$1->isArray=1;
				if($3->numParameters==0)
				{
				      error_flag=1;
				      printf("\nError : Invalid assignment to an array.\n");
				}
				else if( $3->numParameters>$1->ArrayLimit && $1->ArrayLimit>0)
				{	
				      error_flag=1;
				      printf("\nError : List Size greater than Array Size, do not match.\n");
				}
				else if($1->ArrayLimit==0)
				{
				      struct SymEntry *p;
				      p=lookup($1->id,function);
				      p->isArray=1;
				      p->ArrayLimit=$3->numParameters;
				      $1->ArrayLimit=$3->numParameters;
				      $$->ArrayLimit=$1->ArrayLimit;
//PrintAttribute($3);
				      //p->offset=size;//printf("\nsize : %d\n",size);
				      p->offset=$3->ParameterList[0]->offset;
				      size=size+($$->ArrayLimit)*4;//printf("\nsize : %d\n",size);
				      if($1->isPointer==1)
				      {
					    for(counter=0;counter<$1->ArrayLimit;counter++)
					    {
						if(!((($3->ParameterList[counter]->type==200 &&$3->ParameterList[counter]->isString!=1)||$3->type==400||($3->ParameterList[counter]->type==500&&$3->ParameterList[counter]->isPointer==0))\
						||($3->ParameterList[counter]->type==$1->type && $3->ParameterList[counter]->isPointer==1)||($1->specifier==2 && $3->ParameterList[counter]->isString==1)))
						{
						      error_flag=1;
						      printf("\nError : Invalid Assignment to Array Pointers.\n");
						}//PrintAttribute($3->ParameterList[counter]);	
					    }
				      }
				      else
				      {
					    //$1 is not pointer, function so can be int,long,double,float,char type array.
					    
					   fcg=replicate("");
					    icg=replicate("");
					    for(counter=0;counter<$1->ArrayLimit;counter++)
					    {
						if($3->ParameterList[counter]->isFunction==1||$3->ParameterList[counter]->isArray==1||$3->ParameterList[counter]->isPointer==1||$3->ParameterList[counter]->isString==1)
						{
						    error_flag=1;
						    printf("\nError : Invalid Assignment to the Array Variable.\n");
						    //break;
						}
						icg=append(icg,$3->ParameterList[counter]->icode);
						fcg=append(fcg,$3->ParameterList[counter]->code);
						
						sprintf(s1,"\t%s[%d] = %s\n",p->id,counter,$3->ParameterList[counter]->id);
						icg=append(icg,s1);

						sprintf(s1,"\tlw $t0 %s\n",toAddr($3->ParameterList[counter]->offset));
						fcg=append(fcg,s1);
						sprintf(s1,"\tsw $t0 %s\n",toAddr(p->offset+(counter*4)));
					    }
					    $$->code=replicate(fcg);
					    $$->icode=replicate(icg);
				      }
				}
			  }
			  assign_flag=0;
			 
		   }				
	| declarator
	      {
		    if(DEBUGP){
				printf("\ninit_declarator ->declarator\n");
			}
			if($1->isArray==1 && $1->ArrayLimit==0)
			{
			    error_flag=1;
			    printf("\nError : Array Size not defined.\n");
			}
			$$=PassAttribute($1);
			if($1->isPointer==1)
			{
			    $$->offset=size;
			    struct SymEntry *p;
			    p=lookup($1->id,function);
			    p->offset=size;
			    size+=4;
			}
			
		   }					
	;

storage_class_specifier
	: TYPEDEF			{
					      if(DEBUGP){
						      printf("\nstorage_class_specifier found 1\n");
					      }
					      temp_inherited->storage = 1;
					      temp_inherited->type+=10;
					      $$=PassAttribute(temp_inherited);
					      error_flag=1;
					      printf("\nError : This C finctionality is not supported\n");
					}

	| EXTERN			{
					      if(DEBUGP){
						      printf("\nstorage_class_specifier found 2\n");
					      }
					      temp_inherited->storage = 2;
					      temp_inherited->type+=20;
					      $$=PassAttribute(temp_inherited);
					      error_flag=1;
					      printf("\nError : This C finctionality is not supported\n");
					}

	| STATIC			{
					      if(DEBUGP){
						      printf("\nstorage_class_specifier found 3\n");
					      }
					      temp_inherited->storage = 3;
					      temp_inherited->type+=30;
					      $$=PassAttribute(temp_inherited);
					      error_flag=1;
					      printf("\nError : This C finctionality is not supported\n");
					}

	| AUTO				{
					      if(DEBUGP){
						      printf("\nstorage_class_specifier found 4\n");
					      }
					      temp_inherited->storage = 4;
					      temp_inherited->type+=40;
					      $$=PassAttribute(temp_inherited);
					      error_flag=1;
					      printf("\nError : This C finctionality is not supported\n");
					}

	| REGISTER			{
					      if(DEBUGP){
						      printf("\nstorage_class_specifier found 5\n");
					      }
					      temp_inherited->storage = 5;
					      temp_inherited->type+=50;
					      $$=PassAttribute(temp_inherited);
					      error_flag=1;
					      printf("\nError : This C finctionality is not supported\n");
					}
	;

type_specifier
	: VOID				{
					      if(DEBUGP){
						      printf("\ntype_specifier found 1\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 1;
						  temp_inherited->type+=100;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 1;
					      $$->type+=100;
					      //strcpy(temp_inherited->type , "int");
					}

	| CHAR				{
					      if(DEBUGP){
						      printf("\ntype_specifier found 2\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 2;
						  temp_inherited->type+=200;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 2;
					      $$->type+=200;
					}	

	| SHORT				{
					      if(DEBUGP){
						      printf("\ntype_specifier found 3\n");
					      }
					      if(parameter_flag==0)
					      {
						    temp_inherited->specifier = 3;
						    temp_inherited->type+=300;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 3;
					      $$->type+=300;
					}

	| INT				{
					      if(DEBUGP){
						      printf("\ntype_specifier found 4\n");
					      }
					      if(parameter_flag==0)
					      {					      
						  temp_inherited->specifier = 4;
						  temp_inherited->type+=400;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 4;
					      $$->type+=400;
					}

	| LONG				{
					      if(DEBUGP){
						      printf("\ntype_specifier found 5\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 5;
						  temp_inherited->type+=500;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 5;
					      $$->type+=500;
					}

	| FLOAT				{
					      if(DEBUGP){
						      printf("\ntype_specifier found 6\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 6;
						  temp_inherited->type+=600;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 6;
					      $$->type+=600;
					}

	| DOUBLE			{
					      if(DEBUGP){
						      printf("\ntype_specifier found 7\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 7;
						  temp_inherited->type+=700;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 7;
					      $$->type+=700;
					}

	| SIGNED			{
					      if(DEBUGP){
						      printf("\ntype_specifier found 8\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 8;
						  temp_inherited->type+=800;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 8;
					      $$->type+=800;
					}

	| UNSIGNED			{
					      if(DEBUGP){
						      printf("\ntype_specifier found 9\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 9;
						  temp_inherited->type+=900;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 9;
					      $$->type+=900;
					}

	| struct_or_union_specifier	{
					      if(DEBUGP){
						      printf("\ntype_specifier found 10\n");
					      }
					      
					      $$=PassAttribute(temp_inherited);
					}

	| enum_specifier		{
					      if(DEBUGP){
						      printf("\ntype_specifier found 11\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 10;
						  temp_inherited->type+=1000;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 10;
					      $$->type+=1000;
					}

	| TYPE_NAME			{
					      if(DEBUGP){
						      printf("\ntype_specifier found 12\n");
					      }
					      if(parameter_flag==0)
					      {
						  temp_inherited->specifier = 11;
						  temp_inherited->type+=1100;
					      }
					      $$=(struct Attribute*)malloc(sizeof(struct Attribute));
					      $$=initAttr($$);
					      $$->specifier = 11;
					      $$->type+=1100;
					}

	;

struct_or_union_specifier
	: struct_or_union identifier '{' struct_declaration_list '}'
		      {
			    if(DEBUGP){
				    printf("\nstruct_or_union_specifier -> struct_or_union identifier '{' struct_declaration_list '}'\n");
			    }
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			    
		      }
	| struct_or_union '{' struct_declaration_list '}'
		      {
			    if(DEBUGP){
				    printf("\nstruct_or_union_specifier -> struct_or_union '{' struct_declaration_list '}'\n");
			    }		
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| struct_or_union identifier
		      {
			    if(DEBUGP){
				    printf("\nstruct_or_union_specifier -> struct_or_union identifier\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	;

struct_or_union
	: STRUCT
		      {
			    if(DEBUGP){
				    printf("\nstruct_or_union -> STRUCT\n");
			    }	
			    if(parameter_flag==0)
			    {		  
				temp_inherited->specifier=12;
				temp_inherited->type+=120;	
			    }
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->specifier = 12;
			    $$->type+=1200;
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| UNION
		      {
			    if(DEBUGP){
				    printf("\nstruct_or_union -> UNION\n");
			    }	
			    if(parameter_flag==0)
			    {		  
				temp_inherited->specifier=13;  
				temp_inherited->type+=130;
			    }
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->specifier = 13;
			    $$->type+=1300;
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	;

struct_declaration_list
	: struct_declaration
		      {
			    if(DEBUGP){
				    printf("\nstruct_declaration_list -> struct_declaration\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| struct_declaration_list struct_declaration
		      {
			    if(DEBUGP){
				    printf("\nstruct_declaration_list -> struct_declaration_list struct_declaration\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	;

struct_declaration
	: specifier_qualifier_list struct_declarator_list ';'
		      {
			    if(DEBUGP){
				    printf("\nstruct_declaration -> specifier_qualifier_list struct_declarator_list ';'\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	;

specifier_qualifier_list
	: type_specifier specifier_qualifier_list
		      {
			    if(DEBUGP){
				    printf("\nspecifier_qualifier_list -> type_specifier specifier_qualifier_list\n");
			    }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			  
		      }
	| type_specifier
		      {
			    if(DEBUGP){
				    printf("\nspecifier_qualifier_list -> type_specifier\n");
			    }
			    $$=PassAttribute($1);
		      }
	| type_qualifier specifier_qualifier_list
		      {
			    if(DEBUGP){
				    printf("\nspecifier_qualifier_list -> type_qualifier specifier_qualifier_list\n");
			    }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			  
		      }
	| type_qualifier
		      {
			    if(DEBUGP){
				    printf("\nspecifier_qualifier_list -> type_qualifier\n");
			    }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			  
		      }
	;

struct_declarator_list
	: struct_declarator
		      {
			    if(DEBUGP){
				    printf("\nstruct_declarator_list -> struct_declarator\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| struct_declarator_list ',' struct_declarator
		      {
			    if(DEBUGP){
				    printf("\nstruct_declarator_list -> struct_declarator_list ',' struct_declarator\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	;

struct_declarator
	: declarator
		      {
			    if(DEBUGP){
				    printf("\nstruct_declarator -> declarator\n");
			    }			  
			     error_flag=1;
			     printf("\nError : This C finctionality is not supported\n");	
		      }			 		   
	| ':' constant_expression
		      {
			    if(DEBUGP){
				    printf("\nstruct_declarator -> ':' constant_expression\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| declarator ':' constant_expression
		      {
			    if(DEBUGP){
				    printf("\nstruct_declarator -> declarator ':' constant_expression\n");
			    }			  
			    error_flag=1;
			    printf("\nError : This C finctionality is not supported\n");			   
		      }			  
	;

enum_specifier
	: ENUM '{' enumerator_list '}'
		      {
			    if(DEBUGP){
				    printf("\nenum_specifier -> ENUM '{' enumerator_list '}'\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| ENUM identifier '{' enumerator_list '}'
		      {
			    if(DEBUGP){
				    printf("\nenum_specifier -> ENUM identifier '{' enumerator_list '}'\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| ENUM identifier
		      {
			    if(DEBUGP){
				    printf("\nenum_specifier -> ENUM identifier\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	;

enumerator_list
	: enumerator
		      {
			    if(DEBUGP){
				    printf("\nenumerator_list -> enumerator\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| enumerator_list ',' enumerator
		      {
			    if(DEBUGP){
				    printf("\nenumerator_list -> enumerator_list ',' enumerator\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	;

enumerator
	: identifier
		      {
			    if(DEBUGP){
				    printf("\nenumerator -> identifier \n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      }
	| identifier '=' constant_expression
		      {
			    if(DEBUGP){
				    printf("\nenumerator -> identifier '=' constant_expression\n");
			    }			  
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
		      } 
	;

type_qualifier
	  : CONST	{
			  
			    if(DEBUGP){
				    printf("\ntype_qualifier -> CONST\n");
			    }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");
			    /*temp_inherited->qualifier = 1;
			    temp_inherited->type+=1;
			    $$=PassAttribute(temp_inherited);*/
		    }
						  
	| VOLATILE       {
			    if(DEBUGP){
				    printf("\ntype_qualifier -> VOLATILE\n");
			    }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");
			    /*temp_inherited->qualifier = 2;
			    temp_inherited->type+=2;
			    $$=PassAttribute(temp_inherited);*/
			}
			  
	;

declarator
	: pointer declarator
			{
			    if(DEBUGP){
				    printf("\ndeclarator ->pointer direct_declarator\n");
			    }
			    $$=PassAttribute($2);
			    $$->isPointer=1;
			}
			  
	| direct_declarator	
			{
			    if(DEBUGP){
				    printf("\ndeclarator ->direct_declarator\n");
			    }			 
			    //PrintAttribute($1);
			    $$=PassAttribute($1);
			}	
	;

set_parameter_flag
	:	{
		      parameter_flag=1;
		}
	;

unset_parameter_flag
	:	{
		      parameter_flag=0;
		}
	;

direct_declarator
	: identifier	
			{
			      if(DEBUGP){
				    printf("\ndirect_declarator ->identifier\n");
			      }			      
			      //printf("\ndeclaration_flag %d and type of %s is %d %d" , declaration_flag , $1->id, $1->type,$1->scope );
			      
			      if(declaration_flag==1 && parameter_flag==0)
			      {
				  //printf("\nNew variable declared\n");  
				  if($1->type == 0)
				  {
				      $1->type = temp_inherited->storage*10 + temp_inherited->specifier*100;				      
				      $1->isPointer=temp_inherited->isPointer;
				      
				      //$1->isFunction=temp_inherited->isFunction;
				  }
				  else if($1->scope<currentScope)
				  {
				      struct SymEntry *p;
				      $1=InsertSymTable($1->id,currentScope,$1->type,function);
				      $1->type = temp_inherited->storage*10 + temp_inherited->specifier*100;				      
				      $1->isPointer=temp_inherited->isPointer;
				      
				  }
				  else if($1->isFunction==1)
				  {//	PrintSymEntry($1);
				      if($1->type!=temp_inherited->specifier*100)
				      {
					  error_flag=1;
					  printf("\nError : Incompatible with previous definition of function %s \n",$1->id);
				      }
				 }
				 else{
				      printf("\nError : variable %s already defined \n",$1->id);
				  }
				//printf("\n11111111111 %s : Scope %d : type : %d :currentScope %d,function %d\n",$1->id,$1->scope,$1->type,currentScope,function);   
			      }
			      else if(parameter_flag==0)
			      {
				  if($1->type ==  0)
				      printf (" Error : variable type %s not defined \n", $1->id );
			      }			      
			      $$=PassSymEntry($1);
			      if(parameter_flag==0)
			      {
				  $$->specifier=temp_inherited->specifier;
				  //$$->qualifier=temp_inherited->qualifier;
				  $$->storage=temp_inherited->storage;
				  //printf("\ndeclaration_flag %d and type of %s is %d " , declaration_flag , $1->id, $1->type );
			      }
			      
			 }
				
	| '(' declarator ')'	//Pata nahi kya karta hai!!!
			{
			    if(DEBUGP){
				    printf("\ndirect_declarator ->'(' declarator ')'\n");
			     }			      
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			   
			}
	| direct_declarator '[' constant_expression ']'
			{//printf("\nold size %d\n",size);

			    struct SymEntry *p;
			    if(DEBUGP){
				    printf("\ndirect_declarator ->direct_declarator '[' constant_expression ']'\n");
			     }			      
			      //printf("\ndeclaration_flag %d and type of %s is %d parameter_flag : %d" , declaration_flag , $1->id, $1->type,parameter_flag );			      
			      if(declaration_flag==1 && parameter_flag==0)
			      {
				  //printf("\n New variable array declared\n");  
				  if($1->isArray == 0)
				  {
				      $1->type = temp_inherited->storage*10 + temp_inherited->specifier*100;
				      $1->isPointer=temp_inherited->isPointer;
				      $1->isArray=1;				      
				      p=lookup($1->id,function);
				      p->isArray=1;
				      if(!(($3->specifier==2 && $3->isString==0)||$3->specifier==4||$3->specifier==5))
				      {
					    error_flag=1;
					    printf("\nError : Array Size has to an integer\n");
				      }
				      else
				      {
					     $1->ArrayLimit=$3->IntConstValue;
					     p->ArrayLimit=$3->IntConstValue;
//PrintAttribute($1);
					     size=size+($1->ArrayLimit-1)*4;
				      }
				  }
				  else
				  {
				      error_flag=1;
				      printf("\nError : variable %s already defined \n",$1->id);
				  }
			      }
			      else if(parameter_flag==0)
			      {
				  if($1->type ==  0)
				  {
				      error_flag=1;
				      printf (" Error : array variable type %s not defined \n", $1->id );
				  }
			      }
			      $$=PassAttribute($1);
			      /*printf("\n=======================\n");
			      PrintAttribute($1);PrintAttribute($3);*/

			      if(parameter_flag==1)
			      {
				    $$->isArray=1;
				    if(!(($3->specifier==2 && $3->isString==0)||$3->specifier==4||$3->specifier==5))
				    {
					  error_flag=1;
					  printf("\nError : Array Size has to an integer\n");
				    }
				    else
				    {
					    $$->ArrayLimit=$3->IntConstValue;				
				    }
			      }
			      //PrintAttribute($1);PrintAttribute($3);
			      //printf("\ndeclaration_flag %d and type of %s is %d " , declaration_flag , $1->id, $1->type );			      
//printf("\nold size %d\n",size);
			}
	| direct_declarator '[' ']'
			{
			     //PrintAttribute($1);
			     struct SymEntry *p;
			    if(DEBUGP){
				    printf("\ndirect_declarator ->direct_declarator '[' ']'\n");
			     }		//printf("\ndeclaration_flag %d and type of %s is %d,parameter_flag : %d" , declaration_flag , $1->id, $1->type,parameter_flag );
			      if(declaration_flag==0 && parameter_flag==0)
			      {
				 // printf("\n New variable array declared\n");  
				  if($1->isArray == 0)
				  {
				      $1->type = temp_inherited->storage*10 + temp_inherited->specifier*100;//iski zarurat hai nahi shayad.
				      $1->isPointer=temp_inherited->isPointer;
				      $1->isArray=1;				      
				      p=lookup($1->id,function);
				      p->isArray=1;
				      $1->ArrayLimit=0;
				      p->ArrayLimit=0;
				  }
				  else
				  {
				      error_flag=1;
				      printf("\nError : variable %s already defined \n",$1->id);
				  }
			      }
			      else if(parameter_flag==0)
			      {
				  if($1->type ==  0)
				  {
				      error_flag=1;
				      printf (" Error : array variable type %s not defined \n", $1->id );
				  }
			      }
			      $$=PassAttribute($1);
			      $$->isArray=1;
			      
			      //printf("\ndeclaration_flag %d and type of %s is %d " , declaration_flag , $1->id, $1->type );			      	      
			}
	| direct_declarator '(' set_parameter_flag parameter_type_list  unset_parameter_flag ')'
			{
			    if(DEBUGP){
				    printf("\ndirect_declarator ->direct_declarator '(' set_parameter_flag parameter_type_list  unset_parameter_flag ')'\n");
			     }	//PrintAttribute($1);printf("\n===========\n");
			     if((parameter_flag==1&&declaration_flag!=1))
			     {
				  error_flag=1;
				  printf("\nError : Function Overloading/Passing Function as Argument is out of Implemented Scope\n");
			     }
			     else
			     {	      struct SymEntry *p;
				      $1->type = temp_inherited->storage*10 + temp_inherited->specifier*100;//iski zarurat hai nahi shayad.
				      $1->isPointer=temp_inherited->isPointer;
				      $1->isFunction=1;				      
				      p=lookup($1->id,function);
				      //printf("\n===%d\n",linenumber);PrintAttribute($1);printf("\n-----------------\n");				      
				      if(p->isFunction==1)
				      {
					  if(p->numParameters!=$4->numParameters)
					  {
						error_flag=1;
						printf("\nError3 : Function Overloading not possible\n");
					  }
					  else
					  {

					      for(counter=0;counter<$4->numParameters;counter++)
					      {
						  if(p->ParameterList[counter]->type!=$4->ParameterList[counter]->type)
						  {
							error_flag=1;
							printf("\nError4 : Function Overloading not possible\n");
						  }
					      }
					  }
				      }
				      else
				      {
					  p->isFunction=1;
					  //Now pass parameters
					  for(counter=0;counter<$4->numParameters;counter++)
					  {
					      $1->ParameterList[counter]=PassAttribute($4->ParameterList[counter]);
					      p->ParameterList[counter]=PassAttribute($4->ParameterList[counter]);
					  }
					  $1->numParameters=$4->numParameters;
					  p->numParameters=$4->numParameters;
					  //printf("\nM1-----------------\n");PrintSymEntry(p);PrintAttribute($4);printf("\nM2-----------------\n");
				      }
			     }
			      $$=PassAttribute($1);
			      $$->isFunction=1;
			      funcName=(char*)malloc(sizeof(char)*strlen($1->id)+1);
			      strcpy(funcName,$1->id);
			      temp_Parameters=PassAttribute($4);//PrintAttribute($1);printf("\n=00000000000\n");PrintAttribute($4);
			}
	| direct_declarator '(' set_parameter_flag identifier_list unset_parameter_flag ')'
			{
			    
			    if(DEBUGP){
				    printf("\ndirect_declarator -> direct_declarator '('set_parameter_flag identifier_list unset_parameter_flag')'\n");
			     }			      
			      error_flag=1;
			      printf("\nError : Implementation out of Scope of compiler.\n");
			      $$=PassAttribute($1);	
			      funcName=(char*)malloc(sizeof(char)*strlen($1->id)+1);
			      strcpy(funcName,$1->id);		      
			}
	| direct_declarator '(' ')'
			{
			    if(DEBUGP){
				    printf("\ndirect_declarator -> direct_declarator '(' ')'\n");
			     }			      
			     if($1->isFunction==1 || parameter_flag==1)
			     {
				  error_flag=1;
				  printf("\nError : Function Overloading/Passing Function as Argument is out of Implemented Scope\n");
			     }
			     else
			     {	      struct SymEntry *p;
				      $1->type = temp_inherited->storage*10 + temp_inherited->specifier*100;//iski zarurat hai nahi shayad.
				      $1->isPointer=temp_inherited->isPointer;
				      $1->isFunction=1;				      
				      p=lookup($1->id,function);
				      if(p->isFunction==1 && p->numParameters!=0)
				      {
					    error_flag=1;
					    printf("\nError : Function has no arguments according to previous definition\n");
				      }
				      else
				      {
					  p->isFunction=1;
					  //Now pass parameters
					  p->numParameters=0;
					  p->numParameters=0;
				      }
			     }	
			     $$=PassAttribute($1);
			     $$->isFunction=1;
			      funcName=(char*)malloc(sizeof(char)*strlen($1->id)+1);
			      strcpy(funcName,$1->id);
			}
	;

pointer
	: '*'
			{
			    if(DEBUGP){
				    printf("\npointer ->\n");
			     }			      
			      $$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			      $$=initAttr($$);	
			      $$->isPointer=1;
			      if(parameter_flag==0)
			      {
				    temp_inherited->isPointer=1;
			      }
			}
	| '*' type_qualifier_list	//Nahi karna
			{
			    if(DEBUGP){
				    printf("\npointer ->'*' type_qualifier_list\n");
			     }			      
			    error_flag=1;
			      printf("\nError : Out of Implemented Scope\n");
			}
	| '*' pointer			//Nahi karna
			{
			    if(DEBUGP){
				    printf("\npointer ->'*' pointer\n");
			     }			      
			    error_flag=1;
			      printf("\nError : Out of Implemented Scope\n");			      
			}
	| '*' type_qualifier_list pointer	//Nahi karna
			{
			    if(DEBUGP){
				    printf("\npointer ->'*' type_qualifier_list pointer\n");
			     }			      
			    error_flag=1;
			      printf("\nError : Out of Implemented Scope\n");			      
			}
	;

type_qualifier_list
	: type_qualifier
			{
			    if(DEBUGP){
				    printf("\ntype_qualifier_list ->type_qualifier\n");
			     }			      
			    $$=PassAttribute($1);
			}
	| type_qualifier_list type_qualifier
			{
			    if(DEBUGP){
				    printf("\ntype_qualifier_list ->type_qualifier_list type_qualifier\n");
			     }			 
			  error_flag=1;
			  printf("\nError : This C finctionality is not supported\n");			        
			  $$=PassAttribute($1);
			}
	;

parameter_type_list
	: parameter_list
			{
			    if(DEBUGP){
				    printf("\nparameter_type_list -> parameter_list\n");
			     }	
			     $$=PassAttribute($1);
			}
	| parameter_list ',' ELLIPSIS
			{
			    if(DEBUGP){
				    printf("\nparameter_type_list -> parameter_list , ELLIPSIS\n");
			     }	
			     $$=PassAttribute($1);
			     error_flag=1;
			     printf("\nError : Ellipsis is not in the Implemented Scope\n");
			}
	;

parameter_list
	: parameter_declaration
			{
			    if(DEBUGP){
				    printf("\nparameter_list -> parameter_declaration\n");
			     }	
			      $$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			      $$=initAttr($$);	
			      $$->ParameterList[0]=PassAttribute($1);
			      $$->numParameters=1;
			}
	| parameter_list ',' parameter_declaration
			{
			    if(DEBUGP){
				    printf("\nparameter_list -> parameter_list ',' parameter_declaration\n");
			     }			      			
			     $$=PassAttribute($1);
			     $$->ParameterList[$1->numParameters]=PassAttribute($3);
			     $$->numParameters++;
			}
	;

parameter_declaration
	: declaration_specifiers declarator
			{ //Use type info from declaration_specifiers and declarator and delete the declarator->name from symtable.
			    if(DEBUGP){
				    printf("\nparameter_declaration -> declaration_specifiers declarator\n");
			     }
			      //PrintAttribute($2);      

			      $$=PassAttribute($2);
			      //$$->id=replicate($1->id);
			      $$->type=$1->type;
			      $$->specifier=$1->specifier;
			      $$->qualifier=$1->qualifier;
			      if($2->isFunction==1)
			      {
				    error_flag=1;
				    printf("\nError : Function Passing is out of Implemented Scope\n");
			      }
			}
	| declaration_specifiers abstract_declarator
			{
			    if(DEBUGP){
				    printf("\nparameter_declaration -> declaration_specifiers abstract_declarator\n");
			     }
			      $$=PassAttribute($2);
			      $$->specifier=$1->specifier;
			      $$->type=$1->type;
			}
	| declaration_specifiers
			{
			    if(DEBUGP){
				    printf("\nparameter_declaration -> declaration_specifiers\n");
			     }			 
			      $$=PassAttribute($1);
			}
	;

identifier_list
	: identifier
			{
			    if(DEBUGP){
				    printf("\nidentifier_list -> identifier\n");
			     }	
			      $$ = (struct Attribute*)malloc(sizeof (struct Attribute));
			      $$=initAttr($$);	
			      $$->ParameterList[0]=PassSymEntry($1);
			      $$->numParameters=1;
			}
	| identifier_list ',' identifier
			{
			    if(DEBUGP){
				    printf("\nidentifier_list -> identifier_list ',' identifier\n");
			     }			
			     $$=PassAttribute($1);
			     $$->ParameterList[$1->numParameters]=PassSymEntry($3);
			     $$->numParameters++;
			}
	;

type_name
	: specifier_qualifier_list
			{
			    if(DEBUGP){
				    printf("\ntype_name -> specifier_qualifier_list\n");
			     }
				//temporary
				$$ = PassAttribute($1);
			}
	| specifier_qualifier_list abstract_declarator
			{
			    if(DEBUGP){
				    printf("\ntype_name -> specifier_qualifier_list abstract_declarator\n");
			     }//temporary
				$$ = PassAttribute($2);
				$$->specifier=$1->specifier;
				$$->type=$1->type;
			}
	;

abstract_declarator
	: pointer
			{
			    if(DEBUGP){
				    printf("\nabstract_declarator -> pointer\n");
			     }
			     $$=PassAttribute($1);
			}
	| direct_abstract_declarator
			{
			    if(DEBUGP){
				    printf("\nabstract_declarator -> direct_abstract_declarator\n");
			     }
			     $$=PassAttribute($1);
			}
	| pointer direct_abstract_declarator
			{
			    if(DEBUGP){
				    printf("\nabstract_declarator -> pointer direct_abstract_declarator\n");
			     }			  
			      $$=PassAttribute($1);
			      $$->isPointer=1;
			}
	;

direct_abstract_declarator
	: '(' abstract_declarator ')'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> '(' abstract_declarator ')'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");
			}
			
	| '[' ']'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> [ ]\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->isArray=1;
			}
	| '[' constant_expression ']'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> '[' constant_expression ']'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->isArray=1;
			    if(!(($2->specifier==2 && $2->isString==0)||$2->specifier==4||$2->specifier==5))
			      {
				    error_flag=1;
				    printf("\nError : Array Size of Parameter has to an integer\n");
			      }
			      else
			      {
				      $$->ArrayLimit=$2->IntConstValue;				      
			      }			      	      
			}
	| direct_abstract_declarator '[' ']'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> direct_abstract_declarator '[' ']'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			      
			}
	| direct_abstract_declarator '[' constant_expression ']'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> direct_abstract_declarator '[' constant_expression ']'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");
			}
	| '(' ')'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> '(' ')'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			      
			}
	| '(' parameter_type_list ')'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> '(' parameter_type_list ')'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			      
			}
	| direct_abstract_declarator '(' ')'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> direct_abstract_declarator '(' ')'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			      
			}
	| direct_abstract_declarator '(' parameter_type_list ')'
			{
			    if(DEBUGP){
				    printf("\ndirect_abstract_declarator -> direct_abstract_declarator '(' parameter_type_list ')'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");			      
			}
	;

initializer
	: assignment_expression
			{
			    if(DEBUGP){
				    printf("\ninitializer -> assignment_expression\n");
			     }
				$$=PassAttribute($1);
			}
	| '{' initializer_list '}'
			{
			    if(DEBUGP){
				    printf("\ninitializer -> '{' initializer_list '}'\n");
			     }
			  $$=(struct Attribute*)malloc(sizeof (struct Attribute));
			  $$=initAttr($$);
			  if($2->numParameters>0)
			  {
			      $$->numParameters=$2->numParameters;
			      for(counter=0;counter<$2->numParameters;counter++)
			      {
				    $$->ParameterList[counter]=$2->ParameterList[counter];
			      }
			  }
			  else
			  {
			      $$->ParameterList[0]=PassAttribute($2);
			      $$->numParameters=1;
			  }
			}
	| '{' initializer_list ',' '}'		//Pata nahi isme kya karenge,use hi nahi karenge!!
			{
			    if(DEBUGP){
				    printf("\ninitializer -> '{' initializer_list ',' '}'\n");
			     }
			  $$=(struct Attribute*)malloc(sizeof (struct Attribute));
			  $$=initAttr($$);
			  if($2->numParameters>0)
			  {
			      $$->numParameters=$2->numParameters;
			      for(counter=0;counter<$2->numParameters;counter++)
			      {
				    $$->ParameterList[counter]=$2->ParameterList[counter];
			      }
			  }
			  else
			  {
			      $$->ParameterList[0]=PassAttribute($2);
			      $$->numParameters=1;
			  }
			}
	;

initializer_list
	: initializer
			{
			    if(DEBUGP){
				    printf("\ninitializer_list -> initializer\n");
			     }
			    //if($1->numParameters>0)
			    //{
				$$=(struct Attribute*)malloc(sizeof (struct Attribute));
				$$=initAttr($$);
				$$->ParameterList[0]=PassAttribute($1);
				$$->numParameters=1;
			    //}
			    //else
			    //{
			//	$$=PassAttribute($1);
			  //  }
			    //PrintAttribute($$);
			}
	| initializer_list ',' initializer
			{
			    if(DEBUGP){
				    printf("\ninitializer_list -> initializer_list ',' initializer\n");
			     }
				  
			    $$=PassAttribute($1);
			    $$->ParameterList[$$->numParameters]=PassAttribute($3);
			    $$->numParameters++;	
			    //PrintAttribute($$);
			}
	;

statement
	: labeled_statement
			{
			    if(DEBUGP){
				    printf("\nstatement -> labeled_statement\n");
			     }			
			    $$=PassAttribute($1);
			}
	| compound_statement
			{
			    if(DEBUGP){
				    printf("\nstatement -> compound_statement\n");
			     }
			      $$=PassAttribute($1);
			}
	| expression_statement
			{
			    if(DEBUGP){
				    printf("\nstatement -> expression_statement\n");
			     }			
			      $$=PassAttribute($1);
			}
	| selection_statement
			{
			    if(DEBUGP){
				    printf("\nstatement -> selection_statement\n");
			     }			
			      $$=PassAttribute($1);
			}
	| iteration_statement
			{
			    if(DEBUGP){
				    printf("\nstatement -> iteration_statement\n");
			     }			
			      $$=PassAttribute($1);
			}
	| jump_statement
			{
			    if(DEBUGP){
				    printf("\nstatement -> jump_statement\n");
			     }			
			      $$=PassAttribute($1);
			}
	;

labeled_statement
	: identifier ':' statement
			{
			    if(DEBUGP){
				    printf("\nlabeled_statement -> identifier ':' statement\n");
			     }			  
			    error_flag=1;
			    printf("\nError : Labels are out of implemented Scope\n");
			}
	| CASE constant_expression ':' statement
			{
			    if(DEBUGP){
				    printf("\nlabeled_statement -> CASE constant_expression ':' statement\n");
			     }
			      $$=PassAttribute($2);
			    if($2->qualifier!=1||$2->isString==1)
			    {
				error_flag=1;
				printf("\nError : Invalid Label Type\n");
				
			    }			    
			    else
			    {
			      
				  char *fcg,*icg,s1[10000],*l1;
		
				    l1=getNewLabel();//PrintAttribute($2);			     
				    fcg=replicate("\n\n");
				    fcg=append(fcg,$2->code);
				    icg=replicate($2->icode);
				    //PrintAttribute(temp_expression);
				    fcg=append(fcg,temp_expression->code);
				    icg=append(icg,temp_expression->icode);
				    
				    sprintf(s1 , "\tif %s=%s then goto %s \n %s\n\t%s:\n" ,temp_expression->id,$2->id, l1 , $4->icode,l1);
				    icg = append(icg , s1);

				    
				    sprintf( s1 , "\tlw $t0 %s\n" , toAddr($2->offset) );
				    fcg = append( fcg , s1);
				    sprintf( s1 , "\tlw $t1 %s\n" , toAddr(temp_expression->offset) );
				    fcg = append( fcg , s1);
				    sprintf(s1 , "\tbne $t0 $t1 %s\n" , l1);
				    fcg = append( fcg , s1);
				    fcg = append( fcg , $4->code);
				    sprintf(s1 , "\t%s :\n" , l1);
				    fcg = append( fcg , s1);
//				    fcg = append( fcg , "\n\n");
				  $$->code=replicate(fcg);
				  $$->icode=replicate(icg);
			    }  
			}
	| DEFAULT ':' statement
			{
			    if(DEBUGP){
				    printf("\nlabeled_statement -> DEFAULT ':' statement\n");
			     }			      
			      $$=PassAttribute($3);
			      char s1[10000];	
			      
			      $$->icode=replicate($3->icode);
			      sprintf(s1,"\tgoto %s\n",end[currentDepth-1]);
			      $$->icode=append($$->icode,s1);

			      $$->code=replicate("\n\n");
			      $$->code=append($$->code,$3->code);
			      sprintf(s1,"\tj %s\n",end[currentDepth-1]);
			      $$->code=append($$->code,s1);

			}
	;

compound_statement
	: '{' '}'
			{
			    if(DEBUGP){
				    printf("\ncompound_statement -> { } \n");
			     }						      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;  
			    $$->code=replicate("");
			    $$->icode=replicate("");
			    
			}
	| '{' new_scope compound_statement_list finish_scope '}'
			{
			    if(DEBUGP){
				    printf("\ncompound_statement -> '{' new_scope compound_statement_list finish_scope '}' \n");
			     }			
			      $$=PassAttribute($3);   
			}
	| '{' new_scope compound_declaration_list finish_scope '}'
			{
			    if(DEBUGP){
				    printf("\ncompound_statement -> '{' new_scope compound_declaration_list finish_scope'}' \n");
			     }			
			      $$=PassAttribute($3);   
			}
	;

compound_statement_list
	: declaration_list 
			{
			    if(DEBUGP){
				    printf("\ncompound_statement_list -> declaration_list  \n");
			     }			
			      $$=PassAttribute($1);	      
			}
	| declaration_list compound_declaration_list
			{
			    if(DEBUGP){
				    printf("\ncompound_statement_list -> declaration_list compound_declaration_list \n");
			     }					      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;	      
			    $$->code=replicate($1->code);
			    $$->icode=replicate($1->icode);
			    $$->code=append($$->code,$2->code);
			    $$->icode=append($$->icode,$2->icode);
			}
	;

compound_declaration_list
	: statement_list 
			{
			    if(DEBUGP){
				    printf("\ncompound_declaration_list -> statement_list  \n");
			     }					      
			      $$=PassAttribute($1);
			}
	| statement_list compound_statement_list
			{
			    if(DEBUGP){
				    printf("\ncompound_declaration_list -> statement_list compound_statement_list \n");
			     }					      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;	      
			    $$->code=replicate($1->code);
			    $$->icode=replicate($1->icode);
			    $$->code=append($$->code,$2->code);
			    $$->icode=append($$->icode,$2->icode);
			}
	;

declaration_list
	: declaration
			{
			    if(DEBUGP){
				    printf("\ndeclaration_list -> declaration \n");
			     }			
			      $$=PassAttribute($1); 
			}
	| declaration_list declaration
			{
			    if(DEBUGP){
				    printf("\ndeclaration_list -> declaration_list declaration \n");
			     }					      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;	      
			    $$->code=replicate($1->code);
			    $$->icode=replicate($1->icode);
			    $$->code=append($$->code,$2->code);
			    $$->icode=append($$->icode,$2->icode);
			}
	;

statement_list
	: statement
			{
			    if(DEBUGP){
				    printf("\nstatement_list -> statement \n");
			     }			
			      $$=PassAttribute($1);   
			}
	| statement_list statement
			{
			    if(DEBUGP){
				    printf("\nstatement_list -> statement_list statement \n");
			     }				      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;		      
			    $$->code=replicate($1->code);
			    $$->icode=replicate($1->icode);
			    $$->code=append($$->code,$2->code);
			    $$->icode=append($$->icode,$2->icode);
			    
			}
	;

expression_statement
	: ';'
		       {
			    if(DEBUGP){
				    printf("\nexpression_statement -> ';' \n");
			     }					      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;	      
			    $$->code=replicate("");
			    $$->icode=replicate("");assign_flag=0;
			}
	| expression ';'
			{
			    if(DEBUGP){
				    printf("\nexpression_statement -> expression ';' \n");
			     }				      assign_flag=0;
			    $$=PassAttribute($1);//PrintAttribute($$);			    	      
			}
	| expression error 
			{
			    if(DEBUGP){
				    printf("\nexpression_statement -> expression error  \n");
			     }			      
			    printf("\nError : semicolon missing\n " );			      
			     $$=PassAttribute($1);
			    error_flag=1;
			   assign_flag=0;
			}
	;

get_labels
	:	{
		    start[currentDepth]=getNewLabel();
		    end[currentDepth]=getNewLabel();
		    currentDepth++;
		}
      ;

release_labels
	:	{
		    if(start[currentDepth+1]!=NULL)
		    {
			free(start[currentDepth+1]);
			free(end[currentDepth+1]);
		    }
		    currentDepth--;
		}
      ;

switch_label
	:
	    {
		  switch_flag=1;
	    }
	;


release_switch_label
	:
	    {
		  switch_flag=0;
	    }
	;

selection_statement
	: IF '(' expression ')' statement    %prec IFX
			{
			    if(DEBUGP){
				    printf("\nselection_statement -> IF '(' expression ')' if_then_else_branch \n");
			     }
			      $$=PassAttribute($5);   
		  
			      char *fcg,*icg,s1[10000],*l1;
	  
			      l1=getNewLabel();			     
			      fcg=replicate($3->code);
			      icg=replicate($3->icode);
			      
			      sprintf(s1 , "\tif %s=0 then goto %s \n %s\n\t%s:\n" ,$3->id, l1 , $5->icode,l1);
			      icg = append(icg , s1);

			      sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tbeq $t0 $0 %s\n" , l1);
			      fcg = append( fcg , s1);
			      fcg = append( fcg , $5->code);
			      sprintf(s1 , "\t%s:\n" , l1);
			      fcg = append( fcg , s1);
			    $$->code=replicate(fcg);
			    $$->icode=replicate(icg);
			      
			      
			}
	|  IF '(' expression ')' statement ELSE statement
			{
			    if(DEBUGP){
				    printf("\nif_then_else_branch -> statement ELSE statement \n");
			     }		 	 
			      $$=PassAttribute($5);  
			      char *fcg,*icg,s1[10000],*l1,*l2;
	  
			      l1=getNewLabel();
			      l2=getNewLabel();
			      fcg=replicate($3->code);
			      icg=replicate($3->icode);
			      			      
			      sprintf(s1,"\tif %s=0 then goto %s\n",$3->id,l1);
			      icg=append(icg,s1);
			      sprintf(s1,"%s\tgoto %s\n",$5->icode,l2);
			      icg=append(icg,s1);
			      sprintf(s1,"\t%s :\n%s \t%s :\n",l1,$7->icode,l2);
			      icg = append(icg , s1);


			      sprintf( s1 , "\tlw $t0 %s\n" , toAddr($3->offset) );     
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tbeq $t0 $0 %s\n" , l1);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "%s",$5->code);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tj %s\n",l2);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\t%s :\n%s",l1,$7->code);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\t%s :\n",l2);
			      fcg = append( fcg , s1);
			      $$->code=replicate(fcg);
			      $$->icode=replicate(icg);
			}
	| SWITCH get_labels  '(' expression ')' switch_label statement release_switch_label release_labels
			{
			    if(DEBUGP){
				    printf("\nselection_statement -> SWITCH '(' expression ')' statement \n");
			     }
			      
			      $$=PassAttribute($7);  
			      fcg=replicate($4->code);
			      icg=replicate($4->icode);
		      
			      sprintf(s1,"%s",$7->icode);
			      icg=append(icg,s1);
			      sprintf(s1,"\t%s :\n",end[currentDepth]);
			      icg=append(icg,s1);
			
			      sprintf(s1,"%s",$7->code);
			      fcg=append(fcg,s1);
			      sprintf(s1,"\t%s :\n",end[currentDepth]);
			      fcg=append(fcg,s1);
					  
			      $$->code=replicate(fcg);
			      $$->icode=replicate(icg);
			      
			}
	;

/*if_then_else_branch
	:statement     %prec IFX
			{
			    if(DEBUGP){
				    printf("\nif_then_else_branch -> statement     precedence IFX \n");
			     }			 
			      $$=PassAttribute($1);     
			}
	|statement ELSE statement
			{
			    if(DEBUGP){
				    printf("\nif_then_else_branch -> statement ELSE statement \n");
			     }			 
			      $$=PassAttribute($1);     
			}
	;
*/
iteration_statement
	: WHILE get_labels '(' expression ')' statement release_labels
			{
			    if(DEBUGP){
				    printf("\niteration_statement -> WHILE '(' expression ')' statement \n");
			     }		
			     $$=PassAttribute($6);
			       //,*start,*end;
	  
			      //start=getNewLabel();
			      //end=getNewLabel();
			      sprintf(s1,"\t%s :\n",start[currentDepth]);
			      fcg=replicate(s1);
			      icg=replicate(s1);
			      fcg=append(fcg,$4->code);
			      icg=append(icg,$4->icode);
			      			      
			      sprintf(s1,"\tif %s=0 then goto %s\n",$4->id,end[currentDepth]);
			      icg=append(icg,s1);
			      sprintf(s1,"%s\tgoto %s\n",$6->icode,start[currentDepth]);
			      icg=append(icg,s1);
			      sprintf(s1,"\t%s :\n",end[currentDepth]);
			     icg = append(icg , s1);


			      sprintf( s1 , "\tlw $t0 %s\n" , toAddr($4->offset) );     
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tbeq $t0 $0 %s\n" , end[currentDepth]);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "%s",$6->code);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tj %s\n",start[currentDepth]);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\t%s :\n",end[currentDepth]);
			      fcg = append( fcg , s1);
			      $$->code=replicate(fcg);
			      $$->icode=replicate(icg);
			    
			}
	| DO get_labels statement WHILE '(' expression ')' ';' release_labels
			{
			    if(DEBUGP){
				    printf("\niteration_statement -> DO statement WHILE '(' expression ')' ';'\n");
			     }	
			      $$=PassAttribute($3);
			       //,*start;
	  
			      //start=getNewLabel();
			      
			      sprintf(s1,"\t%s :\n",start[currentDepth]);
			      fcg=replicate(s1);
			      icg=replicate(s1);
			      fcg=append(fcg,$3->code);
			      icg=append(icg,$3->icode);
			      			      
			      sprintf(s1,"%s\tif %s!=0 then goto %s\n",$6->icode,$6->id,start[currentDepth]);
			      icg=append(icg,s1);
			     


			      sprintf( s1 , "%s\tlw $t0 %s\n" , $6->code,toAddr($6->offset) );     
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tbne $t0 $0 %s\n" , start[currentDepth]);
			      fcg = append( fcg , s1);
			      $$->code=replicate(fcg);
			      $$->icode=replicate(icg);
			}
	| FOR get_labels '(' expression_statement expression_statement {assign_flag=0;} ')' statement release_labels
			{
			    if(DEBUGP){
				    printf("\niteration_statement -> FOR '(' expression_statement expression_statement ')' statement \n");
			     }		
			      //,*start,*end;
			      $$=PassAttribute($8); 
			      //start=getNewLabel();
			      //end=getNewLabel();
			      fcg=replicate($4->code);
			      icg=replicate($4->icode);
			      sprintf(s1,"\t%s :\n",start[currentDepth]);
			      fcg=append(fcg,s1);
			      icg=append(icg,s1);
			      fcg=append(fcg,$5->code);
			      icg=append(icg,$5->icode);
			      			      
			      sprintf(s1,"\tif %s=0 then goto %s\n",$5->id,end[currentDepth]);
			      icg=append(icg,s1);
			      sprintf(s1,"%s\tgoto %s\n",$8->icode,start[currentDepth]);
			      icg=append(icg,s1);
			      sprintf(s1,"\t%s :\n",end[currentDepth]);
			     icg = append(icg , s1);


			      sprintf( s1 , "\tlw $t0 %s\n" , toAddr($5->offset) );     
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tbeq $t0 $0 %s\n" , end[currentDepth]);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "%s",$8->code);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tj %s\n",start[currentDepth]);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\t%s :\n",end[currentDepth]);
			      fcg = append( fcg , s1);
			      $$->code=replicate(fcg);
			      $$->icode=replicate(icg);
			}
	| FOR get_labels '(' expression_statement expression_statement expression {assign_flag=0;} ')' statement release_labels
			{
			    if(DEBUGP){
				    printf("\niteration_statement -> FOR '(' expression_statement expression_statement expression ')' statement\n");
			     }	
			      
			      $$=PassAttribute($9);     
			      //$$=PassAttribute($6); 
			      //start=getNewLabel();
			      //end=getNewLabel();
			      fcg=replicate($4->code);
			      icg=replicate($4->icode);
			      sprintf(s1,"\t%s :\n",start[currentDepth]);
			      fcg=append(fcg,s1);
			      icg=append(icg,s1);
			      fcg=append(fcg,$5->code);
			      icg=append(icg,$5->icode);
			      sprintf(s1,"\tif %s=0 then goto %s\n",$5->id,end[currentDepth]);
			      icg=append(icg,s1);
			      sprintf(s1,"%s",$9->icode);
			      icg=append(icg,s1);
			      sprintf(s1,"%s\tgoto %s\n",$6->icode,start[currentDepth]);
			      icg=append(icg,s1);
			      sprintf(s1,"\t%s :\n",end[currentDepth]);
			     icg = append(icg , s1);


			      sprintf( s1 , "\tlw $t0 %s\n" , toAddr($5->offset) );     
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\tbeq $t0 $0 %s\n" , end[currentDepth]);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "%s",$9->code);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "%s",$6->code);
			      fcg = append( fcg , s1);			      
			      sprintf(s1 , "\tj %s\n",start[currentDepth]);
			      fcg = append( fcg , s1);
			      sprintf(s1 , "\t%s :\n",end[currentDepth]);
			      fcg = append( fcg , s1);
			      $$->code=replicate(fcg);
			      $$->icode=replicate(icg);
			}
	;

jump_statement
	: GOTO identifier ';'
			{
			    if(DEBUGP){
				    printf("\njump_statement -> GOTO identifier ';'\n");
			     }					      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;			    
			    error_flag=1;
			    printf("\nError : Out of Compiler Implementation Scope\n");			    	      
			}
	| CONTINUE ';'
			{
			    if(DEBUGP){
				    printf("\njump_statement -> CONTINUE ';'\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;			      
			    if(error_flag==0)
			    {
				char s1[10000];
				sprintf(s1,"\tgoto %s\n",start[currentDepth-1]);
				$$->icode=replicate(s1);
				sprintf(s1,"\tj %s\n",start[currentDepth-1]);
				$$->code=replicate(s1);
			    }
			    else
			    {
				 $$->code=replicate("");
				 $$->icode=replicate("");
			    }
			}
	| BREAK ';'
			{
			    if(DEBUGP){
				    printf("\njump_statement -> BREAK ';'\n");
			     }				      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;		      
			    if(error_flag==0)
			    {
				char s1[10000];
				sprintf(s1,"\tgoto %s\n",end[currentDepth-1]);
				$$->icode=replicate(s1);
				sprintf(s1,"\tj %s\n",end[currentDepth-1]);
				$$->code=replicate(s1);
			    }
			    else
			    {
				 $$->code=replicate("");
				 $$->icode=replicate("");
			    }
			}
	| RETURN ';'
			{
			    if(DEBUGP){
				    printf("\njump_statement -> RETURN ';'\n");
			     }				      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;	
			    if(error_flag==0)
			    {
				char s1[10000];				
				sprintf(s1,"\tRETURN return_value 0\n");
				$$->icode=replicate(s1);
				
				sprintf(s1,"\tlw $ra %s\n",toAddr(0));
				$$->code=replicate(s1);				
				
				sprintf(s1,"\tsw $0 %s\n",toAddr(0));
				$$->code=append($$->code,s1);		
				//sprintf(s1,"\tjr $ra\n");
				sprintf(s1,"\tj %s\n",funcEndLabel);
				$$->code=append($$->code,s1);				

			    }
			    else
			    {
				 $$->code=replicate("");
				 $$->icode=replicate("");
			    }
			}
	| RETURN expression ';'
			{
			    if(DEBUGP){
				    printf("\njump_statement -> RETURN expression ';'\n");
			     }				      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;
			    struct Attribute *p;
			    //printf("\n-----------------%s--\n",funcName);
			    p=PassSymEntry(lookup(funcName,0));
			    p->specifier=p->type/100;
			    p->isFunction=0;
			    if($2->type==100)
			    {
				 error_flag=1;
				 printf("\nError : Invalid Return Type\n");
			    }
			   if($2->isFunction==1)
			    {	 
				 error_flag=1;
				 printf("\nError : Cannot have a Function Return Type\n");
			    }
			    if(!(p->isArray==$2->isArray && p->isPointer == $2->isPointer)||CheckBeforeMerge(p,$2))
			    {
				 error_flag=1;
				 printf("\nError : Invalid Return Type\n");
			    }
			    if(error_flag==0)
			    {
				char s1[10000];				

				sprintf(s1,"%s\tRETURN return_value %s\n",$2->icode,$2->id);
				$$->icode=replicate(s1);				
				//$$->code
				sprintf(s1,"%s\tlw $ra %s\n",$2->code,toAddr(0));
				$$->code=replicate(s1);				
				
				sprintf(s1,"\tlw $t0 %s\n",toAddr($2->offset));
				$$->code=append($$->code,s1);

				sprintf(s1,"\tsw $t0 %s\n",toAddr(0));
				$$->code=append($$->code,s1);
				
				//sprintf(s1,"\tjr $ra\n");
				sprintf(s1,"\tj %s\n",funcEndLabel);
				$$->code=append($$->code,s1);
				
			    }
			    else
			    {
				 $$->code=replicate("");
				 $$->icode=replicate("");
			    }
				
			}
	;

strt :
	strt1 { 		
			      fprintf(fcgFile,"%s",$1->code);
			      fprintf(icgFile,"%s",$1->icode);
			      //fprintf(fcgFile,"#Print :\n%s",printcode);
	      }
      ;
strt1
	: external_declaration
			{
			    if(DEBUGP){
				    printf("\nstrt -> new_scope external_declaration finish_scope\n");
			     }			      
			     $$=PassAttribute($1);
			}
	| strt1 external_declaration
			{
			    if(DEBUGP){
				    printf("\nstrt -> strt external_declaration\n");
			     }	
			      $$=PassAttribute($1);
			      $$->code=append($$->code,$2->code);
			      $$->icode=append($$->icode,$2->icode);
			}
	;

external_declaration
	: function_definition
			{
			    if(DEBUGP){
				    printf("\nexternal_declaration -> function_definition\n");
			     }			      				      
			    $$=PassAttribute($1);
			}
	| declaration
			{
			    if(DEBUGP){
				    printf("\nexternal_declaration -> declaration\n");
			     }	
			     $$=PassAttribute($1);
			}
	;

function_scope 
	:	{
		    if(function==1)
		    {
			  error_flag=1;
			  printf("\nError : Cannot Declare a function in a function\n");
		    }
		    funcEndLabel=getNewLabel();
		    function=1;
		    currentScope=-1;	
		    free(global[1]);
		    global[1]=CreateNewSymTableNode();
		    tail[1]=global[1];
		    global[1]->name=(char*)malloc(sizeof(char)*strlen(funcName)+1);
		    strcpy(global[1]->name,funcName);
		    oldsize =size;
		    size=4;
		    //PrintAttribute(temp_Parameters);
		    struct SymEntry *p,*q;
		   //printf("\n--------------------------------\n");
		    if(temp_Parameters->numParameters!=0)
		    {
			  q=lookup(funcName,0);
			  if(q->type != temp_inherited->type)
			  {
			      error_flag=1;
			      printf("\nError : Function Definition not consistent with prevoius definition\n");
			  }
			  if(q->numParameters != temp_Parameters->numParameters)
			  {
			      error_flag=1;
			      printf("\nError1 %d: Function Overloading not possible\n",linenumber);
			  }
			  //PrintSymEntry(q);//rintAttribute(temp_Parameters);
			  for(counter=0;counter<temp_Parameters->numParameters;counter++)
			  {
			      if(q->ParameterList[counter]->type!=temp_Parameters->ParameterList[counter]->type)
			      {
				  printf("\nError2 : Function Overloading not possible\n");
				  error_flag=1;
			      }
			      if(temp_Parameters->ParameterList[counter]->id==NULL)
			      {
				  printf("\nError4 : Varibale name for the parameter is missing\n");
				  error_flag=1;
			      }
			      p=InsertSymTable(temp_Parameters->ParameterList[counter]->id,0,temp_Parameters->ParameterList[counter]->type,function);
			      p->offset=size;
			      size+=4;
			      q->ParameterList[counter]=PassAttribute(temp_Parameters->ParameterList[counter]);
			      
			  }
		    }
		    temp_Parameters=initAttr(temp_Parameters);
//printf("\n--------------------------------\n");
//PrintSymEntry(q);//PrintAttribute(temp_Parameters);
		    //PrintSymEntry(lookup(global[1]->name,0));
	      
		}
	;

unset_function_scope 
	:	{
		    function=0;
		    currentScope=0;
		    size=oldsize;
		}
	;

function_definition	
	: declaration_specifiers declarator declaration_list function_scope get_labels compound_statement release_labels unset_function_scope
			{
			    if(DEBUGP){
				    printf("\nfunction_definition -> declaration_specifiers declarator declaration_list compound_statement\n");
			     } 
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;
			    error_flag=1;
			    printf("\nError : Compiler does not support this feature of C\n");					      
			    
			    sprintf(s1,"\n\t%s :\n",$2->id);
			    fcg=replicate(s1);
			    icg=replicate(s1);
		    
   			    icg=append(icg,$3->icode);
			    icg=append(icg,$6->icode);
			    sprintf(s1,"\tRETURN : END OF SUB ROUTINE\n");
			    icg=append(icg,s1);

			    sprintf(s1,"\tsw $ra 0($sp)\n");
			    fcg=append(fcg,s1);
			    fcg=append(fcg,$3->code);
			    fcg=append(fcg,$6->code);
			    
			    sprintf(s1,"\tlw $ra %s\n",toAddr(0));
			    fcg=append(fcg,s1);	

			    
			    sprintf(s1,"\t%s :\n",funcEndLabel);
			    fcg=append(fcg,s1);
			    sprintf(s1,"\tjr $ra\n");
			    fcg=append(fcg,s1);

			    $$->code=replicate(fcg);
			    $$->icode=replicate(icg);
			}
	| declaration_specifiers declarator function_scope get_labels compound_statement release_labels unset_function_scope
			{
			    if(DEBUGP){
				    printf("\nfunction_definition -> declaration_specifiers declarator compound_statement\n");
			     }			 
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;     

			    
			    sprintf(s1,"\n\t%s :\n",$2->id);
			    fcg=replicate(s1);
			    icg=replicate(s1);
		       			    
			    icg=append(icg,$5->icode);
			    sprintf(s1,"\tRETURN : END OF SUB ROUTINE\n");
			    icg=append(icg,s1);
						    
			    sprintf(s1,"\tsw $ra 0($sp)\n");
			    fcg=append(fcg,s1);
			    fcg=append(fcg,$5->code);
			    sprintf(s1,"\tlw $ra %s\n",toAddr(0));
			    fcg=append(fcg,s1);
	
			    sprintf(s1,"\t%s :\n",funcEndLabel);
			    fcg=append(fcg,s1);
			    sprintf(s1,"\tjr $ra\n");
			    fcg=append(fcg,s1);
	
			    $$->code=replicate(fcg);
			    $$->icode=replicate(icg);
			    
			    
			}
	| declarator declaration_list function_scope get_labels compound_statement release_labels unset_function_scope
			{
			    if(DEBUGP){
				    printf("\nfunction_definition -> declarator declaration_list compound_statement\n");
			     }		
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;
			    error_flag=1;
			    
			    sprintf(s1,"\n\t%s :\n",$2->id);
			    fcg=replicate(s1);
			    icg=replicate(s1);
		    
   			    icg=append(icg,$2->icode);
			    icg=append(icg,$5->icode);
			    sprintf(s1,"\tRETURN : END SUB ROUTINE\n");
			    icg=append(icg,s1);

			    sprintf(s1,"\tsw $ra 0($sp)\n");
			    fcg=append(fcg,s1);
			    fcg=append(fcg,$2->code);
			    fcg=append(fcg,$5->code);
			    
			    sprintf(s1,"\tlw $ra %s\n",toAddr(0));
			    fcg=append(fcg,s1);				
				
	      
			    sprintf(s1,"\t%s :\n",funcEndLabel);
			    fcg=append(fcg,s1);
			    sprintf(s1,"\tjr $ra\n");
			    fcg=append(fcg,s1);

			    $$->code=replicate(fcg);
			    $$->icode=replicate(icg);

			    printf("\nError : Compiler does not support this feature of C\n");			      
			}
	| declarator function_scope get_labels compound_statement release_labels unset_function_scope 
			{
			    if(DEBUGP){
				    printf("\nfunction_definition -> declarator compound_statement\n");
			     }			      
			    $$=(struct Attribute*)malloc(sizeof(struct Attribute));
			    $$=initAttr($$);
			    $$->type=100;
			    $$->specifier=1;
			    //if declarator is not defined then 
			    if(lookup($1->id,0)==NULL)
			    {
				error_flag=1;
				printf("\nError : Compiler does not support this feature of C\n");		
			    }
			    
			    
			    sprintf(s1,"\n\t%s :\n",$1->id);
			    fcg=replicate(s1);
			    icg=replicate(s1);
		       			    
			    icg=append(icg,$4->icode);
			    sprintf(s1,"\tRETURN : END SUB ROUTINE\n");
			    icg=append(icg,s1);
			
			    sprintf(s1,"\tsw $ra 0($sp)\n");
			    fcg=append(fcg,s1);
			    fcg=append(fcg,$4->code);
			    
			    sprintf(s1,"\tlw $ra %s\n",toAddr(0));
			    fcg=append(fcg,s1);	

			    sprintf(s1,"\t%s :\n",funcEndLabel);
			    fcg=append(fcg,s1);
			    sprintf(s1,"\tjr $ra\n");
			    fcg=append(fcg,s1);

			    $$->code=replicate(fcg);
			    $$->icode=replicate(icg);
			}
	;

%%
int CheckBeforeMerge(struct Attribute* a1,struct Attribute* a2){ //For arithmatic operations
	int flag=0;
	//int, (char and notstring), long, short, float.double ke alava kuch ho to operation not valid.
	if(!((a1->specifier==2 && a1->isString==0)||(a1->specifier==4)||(a1->specifier==5)||(a1->specifier==6)||(a1->specifier==7)||(a1->qualifier==1&&a1->isString!=1)))
	{
	    flag=1;
	}
	if(!((a2->specifier==2 && a2->isString==0)||(a2->specifier==4)||(a2->specifier==5)||(a2->specifier==6)||(a2->specifier==7)||(a1->qualifier==1&&a1->isString!=1)))
	{
	    flag=1;
	}
	if(a1->isFunction==1 || (a1->isPointer==1) || a2->isFunction==1 || (a2->isPointer==1))
	{
	    flag=1;
	}
	return flag;
}

struct Attribute * MergeAttributes3Code(struct Attribute* a1,struct Attribute* a2){	//For arithmatic operations
	struct Attribute *a=(struct Attribute*)malloc(sizeof(struct Attribute));
	a->isArray=0;
	a=initAttr(a);
	if((a1->specifier==4 || a1->specifier==5) && (a2->specifier==4 || a2->specifier==5))
	{
	    a->specifier=a1->specifier;
	    if(a2->specifier==5)
	    {
		a->specifier=5;
	    }
	}
	else if((a1->specifier==4 || a1->specifier==5) && (a2->specifier==6 || a2->specifier==7))
	{
	    a->specifier=a2->specifier;	    
	}
	else if((a1->specifier==6 || a1->specifier==7) && (a2->specifier==4 || a2->specifier==5))
	{
	    a->specifier=a1->specifier;	    
	}
	a->type=a->specifier*100;
	return a;
}
	
struct Attribute * initAttr(struct Attribute* dest){
	//dest->Type[0]='\0'; 
	int i=0;
	dest->id=NULL;
	dest->type=0;	
	dest->isArray=0;		// True if variable is array
	dest->ArrayLimit=0;	// upper limit of array (valid if DIMENSION is true)
	dest->width=0;
	//dest->isptrConst=0;
	dest->isPointer=0;
	dest->qualifier=0;
	dest->specifier=0;
	dest->storage=0;
	dest->scope=0;
	dest->IntConstValue=0;		// because this g++ compiler set 4 byte for long but we are setting 8 bytes
	dest->IntConst=0;
	dest->FloatConstValue=0;			// to store the value of double or float
	dest->StringValue=NULL;
	dest->isString=0;
	dest->code=NULL;	//For intermediate code generation	//  
	dest->icode=NULL;
	dest->offset=0;			// 0 means not
	dest->numParameters=0;
	//dest->isdoubleptr=0;
	dest->isFunction=0;
	for(i=0;i<MaxPar;i++)
	  dest->ParameterList[i]=NULL;

	//return dest;
	//class_definition=0;
//	set_temp 0;
	return dest;
	
}

struct Attribute *PassSymEntry(struct SymEntry *a1)
{
	int i=0;
	struct Attribute *a=(struct Attribute*)malloc(sizeof(struct Attribute));
	if(a1->id!=NULL)
	{
	      a->id=(char *)malloc(sizeof(char)*strlen(a1->id)+1);
	      strcpy(a->id,a1->id);
	}
	else
	{
	      a->id=NULL;
	}
	a->type=a1->type;
	a->isArray=a1->isArray;
	a->ArrayLimit=a1->ArrayLimit;
	a->isPointer=a1->isPointer;
	a->scope=a1->scope;
	a->isFunction=a1->isFunction;
	a->isString=0;
	a->offset=a1->offset;
	a->numParameters=a1->numParameters;
	a->code=NULL;
	a->icode=NULL;
	a->StringValue=NULL;
	a->IntConstValue=0;		// because this g++ compiler set 4 byte for long but we are setting 8 bytes
	a->IntConst=0;
	a->specifier=0;
	a->qualifier=0;
	a->storage=0;
	a->FloatConstValue=0;
	//ParameterList
	for(i=0;i<MaxPar;i++)
	{
	    if(a1->ParameterList[i]==NULL)
	    {
		  break;
	    }
	    a->ParameterList[i]=a1->ParameterList[i];
	}
	return a;
}
struct Attribute *PassAttribute(struct Attribute *a1)
{	
	int i=0;
	struct Attribute *a=(struct Attribute*)malloc(sizeof(struct Attribute));
	if(a1->id!=NULL)
	{
	      a->id=(char *)malloc(sizeof(char)*strlen(a1->id)+1);
	      strcpy(a->id,a1->id);
	}
	else
	{
	      a->id=NULL;
	}
	a->type=a1->type;
	a->isArray=a1->isArray;
	a->ArrayLimit=a1->ArrayLimit;
	a->width=a1->width;
	a->isPointer=a1->isPointer;
	a->qualifier=a1->qualifier;
	a->specifier=a1->specifier;
	a->storage=a1->storage;
	a->scope=a1->scope;
	a->IntConstValue=a1->IntConstValue;
	a->IntConst=a1->IntConst;
	a->FloatConstValue=a1->FloatConstValue;
	a->isFunction=a1->isFunction;
	a->isString=a1->isString;
	a->offset=a1->offset;
	a->numParameters=a1->numParameters;
	if(a1->StringValue!=NULL)
	{
	      a->StringValue=(char *)malloc(sizeof(char)*strlen(a1->StringValue)+1);
	      strcpy(a->StringValue,a1->StringValue);
	}
	else
	{
	      a->StringValue=NULL;
	}
	if(a1->code!=NULL &&a1->icode!='\0')
	{
	      a->code=replicate(a1->code);
	      //a->code=(char *)malloc(sizeof(char)*strlen(a1->code)+1);
	      //strcpy(a->code,a1->code);
	}
	else
	{
	      a->code=(char *)malloc(sizeof(char)*2);		
	      strcpy(a->code,"");
			
	}
	if(a1->icode!=NULL &&a1->icode!='\0')
	{//printf("\n---------\n");
	      a->icode=replicate(a1->icode);
	      //a->icode=(char *)malloc(sizeof(char)*strlen(a1->icode)+1);
	      //strcpy(a->icode,a1->icode);
	}
	else
	{
	      	a->icode=(char *)malloc(sizeof(char)*2);
		strcpy(a->icode,"");
	}
	//ParameterList
	for(i=0;i<a1->numParameters;i++)
	{
	    if(a1->ParameterList[i]==NULL)
	    {
		  break;
	    }
	    a->ParameterList[i]=PassAttribute(a1->ParameterList[i]);
	}
	return a;
}

void PrintAttribute(struct Attribute *a)
{	
	if(a==NULL)
	{
	    printf("Attribute is not defined Yet\n");
	}
	else
	{
	      int i=0;
	      printf("\nAttribute ID : ");
	      if(a->id!=NULL)
	      {	
		    printf("%s",a->id);
	      }
	      printf(",Type :%d ,isArray :%d ,ArrayLimit :%d ,width :%d ,",a->type,a->isArray,a->ArrayLimit,a->width);
	      printf("isPointer :%d ,qualifier :%d ,specifier :%d ,storage :%d ,",a->isPointer,a->qualifier,a->specifier,a->storage);
	      printf("scope :%d ,IntConstValue :%lli ,IntConst :%d ,FloatConstValue :%f ,",a->scope,a->IntConstValue,a->IntConst,a->FloatConstValue);
	      
	      if(a->StringValue!=NULL)
	      {	
		    printf("StringValue : %s ,",a->StringValue);
	      }
	      printf("isFunction : %d ,numParameters %d ,isString : %d ,offset : %d ,",a->isFunction,a->numParameters,a->isString,a->offset);
	      if(a->code!=NULL)
	      {	
		    printf("Code :\n %s \n",a->code);
	      }
	      if(a->code!=NULL)
	      {	
		    printf("Intermediate Code :\n %s \n",a->icode);
	      }
	      printf(" Parameters :");
	      for(i=0;i<a->numParameters;i++)
	      {
		  printf("Parameter %d\n",(i+1));
		  if(a->ParameterList[i]==NULL)
		  {
			break;
		  }
		  
		  PrintAttribute(a->ParameterList[i]);
	      }
	      printf(" Attribute Printed \n");
	}
}
void PrintSymEntry(struct SymEntry *a)
{	
	if(a==NULL)
	{
	    printf("SymEntry is not defined Yet\n");
	}
	else
	{
	      int i=0;
	      printf("\nSymEntry ID : ");
	      if(a->id!=NULL)
	      {	
		    printf("%s",a->id);
	      }
	      printf(",Type :%d ,isArray :%d ,ArrayLimit :%d ,width :%d ,",a->type,a->isArray,a->ArrayLimit,a->width);
	      printf("isPointer :%d ,",a->isPointer);
	      printf("scope :%d ,",a->scope);
	      
	      printf("isFunction : %d ,numParameters %d ,offset : %d ,",a->isFunction,a->numParameters,a->offset);	      
	      printf(" Parameters :");
	      for(i=0;i<a->numParameters;i++)
	      {
		  if(a->ParameterList[i]==NULL)
		  {
			break;
		  }
		  printf("Parameter %d\n",(i+1));
		  PrintAttribute(a->ParameterList[i]);
	      }
	      printf(" SymEntry Printed \n");
	}
}


main()
{

	char * outfilename = malloc (100);
	strcpy (outfilename, "/home/agasheesh/Desktop/Compiler_Project/code.asm");
	fcgFile = fopen (outfilename, "w");

	fprintf(fcgFile , "\t.data\n");
	fprintf(fcgFile , "str:\n");
	fprintf(fcgFile , ".asciiz \" : is answer \\n\"\n");
	fprintf(fcgFile , ".text\n");
	fprintf(fcgFile , ".globl main\n");
	//fprintf(fcgFile , "main:\n");
	
	char * outfilename1 = malloc (100);
	strcpy (outfilename1, "IntermediateCode.txt");
	icgFile = fopen (outfilename1, "w");
	
        InitializeSymTable(-1); //Type = -1 for keywords.
	DEBUGP=0;
	printcode=replicate("");
	temp_inherited = (struct Attribute*)malloc(sizeof (struct Attribute));
	temp_inherited = initAttr(temp_inherited);
	temp_Parameters = (struct Attribute*)malloc(sizeof (struct Attribute));
	temp_Parameters = initAttr(temp_Parameters);
	temp_expression = (struct Attribute*)malloc(sizeof (struct Attribute));
	temp_expression = initAttr(temp_expression);

	do{
		yyparse();
	}while(!feof(yyin));
	char *str="i";
	struct SymEntry * p=lookup(str,function);
	//if(p==NULL)
	    //printf("\nVarible i not found\n");
	//else 
	   // printf("\nVarible i found in linenum %d\n",p->linenum);
	//PrintSymTable();

	fclose (fcgFile);fclose (icgFile);

}
yyerror(s)
char *s;
{
	fflush(stdout);
	printf("\nSyntax Error on Line %d\n",linenumber);//"\n\n%*s\n%*s\n", column, "^", column, s);
}

